Commit 7f8a0cc9 authored by Mattias J Duffy's avatar Mattias J Duffy
Browse files

merging in new-card-design

parents d1a9fb89 ce4b9510
Pipeline #1770 passed with stage
in 1 minute and 41 seconds
......@@ -24,3 +24,4 @@ yarn-error.log*
#local dotfiles
/.storybook
/src/stories
/src/styles/whatsOpen.css
......@@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"array-sort": "^0.1.4",
"autosuggest-highlight": "^3.1.0",
"classnames": "^2.2.5",
"fuzzysearch": "^1.0.3",
......@@ -12,6 +13,8 @@
"mapbox-gl": "^0.40.1",
"material-ui": "next",
"material-ui-icons": "^1.0.0-alpha.19",
"node-sass-chokidar": "^0.0.3",
"npm-run-all": "^4.1.1",
"prop-types": "^15.5.10",
"react": "^15.6.1",
"react-autosuggest": "^9.3.2",
......@@ -29,8 +32,12 @@
},
"proxy": "http://localhost:3001",
"scripts": {
"start": "react-scripts start ",
"build": "react-scripts build",
"build-css": "node-sass-chokidar src/styles/whatsOpen.scss -o src/styles/",
"watch-css": "npm run build-css --watch --recursive",
"start-js": "react-scripts start",
"start": "npm-run-all -p watch-css start-js",
"build-js": "react-scripts build",
"build": "npm-run-all build-css build-js",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"storybook": "start-storybook -p 9009 -s public",
......
......@@ -2,7 +2,7 @@ export const TOGGLE_SIDEBAR = 'TOGGLE_SIDEBAR';
export const TOGGLE_SIDEBAR_MAP = 'TOGGLE_SIDEBAR_MAP';
export const SET_FACILITIES = 'SET_FACILITIES';
export const GET_FACILITIES = 'GET_FACILITIES';
export const SET_SIDEBAR = 'SET_SIDEBAR';
export const SET_SELECTED_FACILITY = 'SET_SELECTED_FACILITY';
export const SET_SEARCH_TERM = 'SET_SEARCH_TERM';
export const ADD_FAVORITE_FACILITY = 'ADD_FAVORITE_FACILITY';
export const REMOVE_FAVORITE_FACILITY = 'REMOVE_FAVORITE_FACILITY';
......
......@@ -2,10 +2,9 @@ import {
ADD_FAVORITE_FACILITY,
REMOVE_FAVORITE_FACILITY,
SET_SEARCH_TERM,
SET_SIDEBAR,
TOGGLE_SIDEBAR,
TOGGLE_SIDEBAR_MAP,
SET_ALL_FAVORITES
SET_ALL_FAVORITES, SET_SELECTED_FACILITY
} from './action-types';
export const toggleSidebar = () => ({
......@@ -16,9 +15,9 @@ export const toggleSidebarMap = () => ({
type: TOGGLE_SIDEBAR_MAP,
});
export const setSidebar = (facility) => ({
type: SET_SIDEBAR,
facility,
export const setSelectedFacility = (facility) => ({
type: SET_SELECTED_FACILITY,
facility
});
export const setSearchTerm = (term) => ({
......
import React from 'react';
import PropTypes from 'prop-types';
import {withStyles, withTheme} from 'material-ui/styles';
import AppBar from 'material-ui/AppBar';
import Toolbar from 'material-ui/Toolbar';
import Typography from 'material-ui/Typography';
import Button from 'material-ui/Button';
import IconButton from 'material-ui/IconButton';
import MenuIcon from 'material-ui-icons/Menu';
import {compose} from 'redux';
import classNames from 'classnames'
class CustomAppBar extends React.Component {
......@@ -29,25 +26,24 @@ class CustomAppBar extends React.Component {
render() {
return (<div>
<AppBar position="absolute" className={this.props.classes.appBar}>
<Toolbar className={this.props.classes.toolBar}>
<img src={require('../images/SRCT_square.svg')} className={this.props.classes.navbarLogo}/>
<Typography type="title"
className={classNames(this.props.classes.title, this.props.classes.navbarTextColor)}>
<AppBar position="absolute" className={'app-bar'}>
<Toolbar className={'app-bar-tool-bar'}>
<img src={require('../images/SRCT_square.svg')} className={'app-bar-logo'}/>
<Typography type="title" className={classNames('app-bar-title', 'app-bar-text-color')}>
What's Open
</Typography>
<IconButton onClick={this.toggleExpand} aria-label="Menu"
className={classNames(this.props.classes.appBarMenuButton, this.props.classes.navbarTextColor)}>
className={classNames('app-bar-menu-button', 'app-bar-text-color')}>
<MenuIcon/>
</IconButton>
<div
className={classNames(this.props.classes.linkContainer, !this.state.isAppBarExpanded && this.props.classes.hide)}>
className={classNames('app-bar-link-container', !this.state.isAppBarExpanded && 'app-bar-hide')}>
<Button
className={classNames(this.props.classes.appBarLinkButton, this.props.classes.navbarTextColor)}>
className={classNames('app-bar-link-button', 'app-bar-text-color')}>
About
</Button>
<Button
className={classNames(this.props.classes.appBarLinkButton, this.props.classes.navbarTextColor)}>
className={classNames('app-bar-link-button', 'app-bar-text-color')}>
Feedback
</Button>
</div>
......@@ -57,51 +53,4 @@ class CustomAppBar extends React.Component {
};
}
CustomAppBar.propTypes = {
classes: PropTypes.object.isRequired,
};
const styleSheet = {
'@media screen and (max-width: 600px)': {
appBarLinkButton: {
display: 'block',
padding: 0,
textAlign: 'left'
},
appBarMenuButton: {
display: 'inherit !important'
},
hide: {
maxHeight: '0 !important',
overflow: 'hidden'
},
toolBar: {
flexWrap: 'wrap',
},
linkContainer: {
display: 'block',
flexBasis: '100%',
transition: 'ease-in-out 2s'
}
},
appBar: {
backgroundColor: 'white',
boxShadow: '0px 1px 0px 0px rgba(0, 0, 0, 0.2)'
},
title: {
marginRight: 'auto',
},
appBarMenuButton: {
display: 'none'
},
navbarLogo: {
width: '30px',
height: '30px',
marginRight: '5px'
},
navbarTextColor: {
color: '#354052'
},
};
export default compose(withStyles(styleSheet), withTheme)(CustomAppBar);
export default CustomAppBar;
......@@ -3,32 +3,22 @@ import {withStyles} from 'material-ui/styles';
import FacilityCard from '../containers/FacilityCard'
import Grid from 'material-ui/Grid';
const CardContainer = ({classes, searchTerm, facilities}) => {
const CardContainer = ({searchTerm, facilities}) => {
const filterCards = (facility) => {
const name = facility.facility_name.toLowerCase()
return name.includes(searchTerm.toLowerCase())
}
return (
<Grid container className={classes.root} spacing={24} justify={'center'} align={'flex-end'}>
{facilities.filter(filterCards).map(item => {
return (
<Grid container className={'card-container-root'} spacing={24} justify={'center'} align={'flex-end'}>
{facilities.filter(filterCards).map(item =>{
return(
<Grid key={item.slug} item>
<FacilityCard facility={item}/>
<FacilityCard facility={item} facilities={facilities}/>
</Grid>
)
})}
</Grid>
)
}
const styleSheet = {
root: {
// backgroundColor:'red',
margin: 0,
width: '100%',
display: 'flex',
flexWrap: 'wrap',
},
}
export default withStyles(styleSheet)(CardContainer)
\ No newline at end of file
export default CardContainer;
\ No newline at end of file
......@@ -66,30 +66,30 @@ class FacilitiesMap extends React.Component {
}
}
componentWillReceiveProps = (nextProps) =>{
try {
const coordsArr = nextProps.facility.facility_location.coordinate_location.coordinates
const coordsObj = {latitude:coordsArr[1],longitude:coordsArr[0]}
if(this.state.positionReady){
getGeoLine(client,this.state.position,coordsObj,()=>{}).then((route)=>{
const coords = route.geometry.coordinates
const bounds = coords.reduce(function(bounds, coord) {
return bounds.extend(coord);
}, new mapboxgl.LngLatBounds(coords[0], coords[0]));
const boundsArr = [[bounds._sw.lng,bounds._sw.lat],[bounds._ne.lng,bounds._ne.lat]]
console.log(bounds)
console.log(boundsArr)
this.setState({
mappedRoute:coords,
fitBounds:boundsArr,
fitBoundsOptions:{padding:20},
})
})
}
}catch(e){
// componentWillReceiveProps = (nextProps) =>{
// try {
// const coordsArr = nextProps.facility.facility_location.coordinate_location.coordinates
// const coordsObj = {latitude:coordsArr[1],longitude:coordsArr[0]}
// if(this.state.positionReady){
// getGeoLine(client,this.state.position,coordsObj,()=>{}).then((route)=>{
// const coords = route.geometry.coordinates
// const bounds = coords.reduce(function(bounds, coord) {
// return bounds.extend(coord);
// }, new mapboxgl.LngLatBounds(coords[0], coords[0]));
// const boundsArr = [[bounds._sw.lng,bounds._sw.lat],[bounds._ne.lng,bounds._ne.lat]]
// console.log(bounds)
// console.log(boundsArr)
// this.setState({
// mappedRoute:coords,
// fitBounds:boundsArr,
// fitBoundsOptions:{padding:20},
// })
// })
// }
// }catch(e){
}
}
// }
// }
render (){
......@@ -100,7 +100,12 @@ class FacilitiesMap extends React.Component {
<div className={classes.mapContainer} style={{'height': isMapOpen ? '400px' : 0}}>
<Map
onStyleLoad={(map,e)=>{
map.addControl(new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
trackUserLocation: true
}));
}}
style="mapbox://styles/mapbox/streets-v9"
movingMethod={'easeTo'}
......@@ -118,18 +123,12 @@ class FacilitiesMap extends React.Component {
key={item.slug}
coordinates={item.facility_location.coordinate_location.coordinates}
anchor="bottom">
{/* <img height={20} width={20} src={require('../images/starbucksSVG.svg')}/> */}
<div style={Mark}></div>
<img height={20} width={20} src={require('../images/starbucksSVG.svg')}/>
{/* <div style={Mark}></div> */}
</Marker>
)
})}
{<Layer
type="line"
layout={{"line-join": "round","line-cap": "round"}}
paint={{"line-color": "#888","line-width": 5}}
>
{mappedRoute && <Feature coordinates={mappedRoute}/>}
</Layer>}
</Map>
</div>
)
......@@ -137,9 +136,18 @@ class FacilitiesMap extends React.Component {
}
const styleSheet = {
mapContainer: {
transition: '250ms ease-in-out'
transition: '250ms ease-in-out',
width: '100%'
}
};
export default withStyles(styleSheet)(FacilitiesMap)
\ No newline at end of file
export default withStyles(styleSheet)(FacilitiesMap)
// {<Layer
// type="line"
// layout={{"line-join": "round","line-cap": "round"}}
// paint={{"line-color": "#888","line-width": 5}}
// >
// {mappedRoute && <Feature coordinates={mappedRoute}/>}
// </Layer>}
\ No newline at end of file
......@@ -11,7 +11,7 @@ import FitnessCenterIcon from 'material-ui-icons/FitnessCenter';
import ShoppingCartIcon from 'material-ui-icons/ShoppingCart'
import {red, blue, brown, grey, teal, deepOrange, lime} from 'material-ui/colors';
const FacilityCategory = ({classes, category}) => {
const FacilityCategory = ({category}) => {
const generateAvatar = () => {
let color;
......@@ -42,43 +42,43 @@ const FacilityCategory = ({classes, category}) => {
case 2: //Restaurant
case 5: //Take out dining hall
color = red[400];
icon = <RestaurantIcon className={classes.categoryIcon}/>;
icon = <RestaurantIcon className={'facility-category-icon'}/>;
break;
case 3: //Convenience Store
color = blue[500];
icon = <StoreIcon className={classes.categoryIcon}/>;
icon = <StoreIcon className={'facility-category-icon'}/>;
break;
case 4: //Cafe
color = brown[500];
icon = <LocalCafeIcon className={classes.categoryIcon}/>;
icon = <LocalCafeIcon className={'facility-category-icon'}/>;
break;
case 6: //Athletic Facility
color = teal[500];
icon = <FitnessCenterIcon className={classes.categoryIcon}/>;
icon = <FitnessCenterIcon className={'facility-category-icon'}/>;
break;
case 7: //TODO: Print Services - NOT IN API
color = grey[500];
icon = <LocalPrintShopIcon className={classes.categoryIcon} />;
icon = <LocalPrintShopIcon className={'facility-category-icon'} />;
break;
case 8: //TODO Mailroom - NOT IN API
color = deepOrange[500];
icon = <LocalPostOfficeIcon className={classes.categoryIcon}/>;
icon = <LocalPostOfficeIcon className={'facility-category-icon'}/>;
break;
default:
color = lime[500];
icon = <ShoppingCartIcon className={classes.categoryIcon}/>
icon = <ShoppingCartIcon className={'facility-category-icon'}/>
}
return (
<Avatar className={classes.avatar} style={{backgroundColor: color}}>
<Avatar className={'facility-category-avatar'} style={{backgroundColor: color}}>
{icon}
</Avatar>
)
};
return (
<div className={classes.categoryWrapper}>
{generateAvatar()}
<div className={'facility-category-wrapper'}>
{/* {generateAvatar()} */}
<Typography type={'body1'} noWrap>
{category.name}
</Typography>
......@@ -86,21 +86,4 @@ const FacilityCategory = ({classes, category}) => {
)
};
const styleSheet = {
categoryWrapper: {
display: 'flex',
alignItems: 'center'
},
categoryIcon: {
width: '14px !important',
height: '14px !important',
padding: '4px !important',
},
avatar: {
width: 'auto !important',
height: 'auto !important',
marginRight: '8px'
},
};
export default withStyles(styleSheet)(FacilityCategory);
\ No newline at end of file
export default FacilityCategory;
\ No newline at end of file
import React from 'react';
import {withStyles} from 'material-ui/styles';
import Typography from 'material-ui/Typography';
import DoneIcon from 'material-ui-icons/Done';
import CloseIcon from 'material-ui-icons/Close';
import {green, red} from 'material-ui/colors'
import FacilityUtils from '../utils/facilityUtils';
import classNames from 'classnames';
const FacilityStatus = ({classes, facility}) => {
const FacilityStatus = ({facility}) => {
/**
* Generates information about the facility's status.
......@@ -16,52 +13,33 @@ const FacilityStatus = ({classes, facility}) => {
*/
const generateStatusInfo = facility => {
let label;
let color;
let icon;
let isOpen;
if (FacilityUtils.getFacilityActiveSchedule(facility).twenty_four_hours) {
label = 'OPEN 24/7';
color = green[500];
icon = <DoneIcon/>;
isOpen = true;
} else if (FacilityUtils.isFacilityOpen(facility)) {
label = 'OPEN';
color = green[500];
icon = <DoneIcon/>;
}else {
isOpen = true;
} else {
label = 'CLOSED';
color = red[500];
icon = <CloseIcon/>
isOpen = false;
}
return {
label: label,
color: color,
icon: icon,
isOpen: isOpen,
}
};
const statusInfo = generateStatusInfo(facility);
return (
<Typography type={'caption'} className={classes.statusText} style={{color: statusInfo.color}}>
{statusInfo.icon}
<Typography type={'caption'} className={classNames('facility-status-text', statusInfo.isOpen ? 'facility-status-open' : 'facility-status-closed')}>
{/*{statusInfo.icon}*/}
{statusInfo.label}
</Typography>
)
};
const styleSheet = {
statusText: {
display: 'flex',
alignItems: 'center'
},
chip: {
height: '28px',
borderRadius: '4px',
},
isOpenText: {
color: 'white',
display: 'inline',
}
};
export default withStyles(styleSheet)(FacilityStatus);
\ No newline at end of file
export default FacilityStatus;
\ No newline at end of file
......@@ -4,16 +4,18 @@ import pink from 'material-ui/colors/pink';
import FavoriteBorderIcon from 'material-ui-icons/FavoriteBorder';
import FavoriteIcon from 'material-ui-icons/Favorite';
import PropTypes from 'prop-types';
import classNames from 'classnames';
class FavoriteButton extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.state = {
isHovered: false,
}
}
handleClick(e) {
handleClick = (e) => {
e.stopPropagation(); //Stops the card from being selected in the sidebar.
if (this.props.isFavorite) {
......@@ -21,36 +23,24 @@ class FavoriteButton extends React.Component {
} else {
this.props.addFavoriteFacility(this.props.facility.slug);
}
}
};
render() {
const {isHovered} = this.props;
if (this.props.isFavorite) {
return (<FavoriteIcon onClick={this.handleClick} className={this.props.classes.heart}/>);
return (<FavoriteIcon onClick={this.handleClick} className={classNames('favorite-button-heart', 'favorite-button-heart-favorited')}/>);
}
return (<FavoriteBorderIcon onClick={this.handleClick} className={this.props.classes.heart}/>);
return (<FavoriteBorderIcon onClick={this.handleClick} className={classNames('favorite-button-heart', isHovered ? 'favorite-button-heart-hover' : 'favorite-button-heart-no-hover')}/>);
}
}
FavoriteButton.propTypes = {
classes: PropTypes.object.isRequired,
facility: PropTypes.object.isRequired,
isFavorite: PropTypes.bool.isRequired,
addFavoriteFacility: PropTypes.func.isRequired,
removeFavoriteFacility: PropTypes.func.isRequired,
};
const styleSheet = {
heart: {
position: 'absolute',
top: '0px',
right: '0px',
height: '24px',
width: '24px',
padding: '5px',
cursor: 'pointer',
color: pink[500]
}
};
export default withStyles(styleSheet)(FavoriteButton);
\ No newline at end of file
export default FavoriteButton;
\ No newline at end of file
import React from 'react';
import {withStyles } from 'material-ui/styles';
import Paper from 'material-ui/Paper'
import Avatar from 'material-ui/Avatar'
import Typography from 'material-ui/Typography'
......@@ -9,103 +8,51 @@ import FacilitiesMap from '../components/FacilitiesMap'
import classNames from 'classnames';
import Button from 'material-ui/Button';
const Sidebar = ({classes,facility,isSidebarOpen,isSidebarMapOpen,toggleSidebarMap,facilities}) => {
const Sidebar = ({facility, isSidebarOpen, isSidebarMapOpen, toggleSidebarMap, facilities}) => {
const removeBrackets = (name) => {
if(typeof(name) === "undefined"){
return ""
}
const openBracket = name.indexOf('[')
if(openBracket !== -1){
return name.substring(0,openBracket)
if (typeof(name) === "undefined") {
return "";
}
return name
}
// if(isSidebarOpen){
// return (<div></div>)
// }
return(
<Paper className={classNames([classes.root,(!isSidebarOpen && classes.openSidebar),(isSidebarOpen && classes.closedSidebar)])}>
<div className={classes.row1}>
<Avatar className={classes.avatar} src={require('../images/chipotleLogo.png')} />
<div className={classes.title}>
<Typography type='display1'>{removeBrackets(facility.facility_name)}</Typography>
</div>
</div>
<Divider className={classes.divider}/>
<div className={classes.labelHolder}>
<div className={classes.labelRow}>
<TextwTitle label="Location" content="The Johnson Center" />
<TextwTitle label="Location" content="The Johnson Center" />
</div>