You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
193 lines
5.5 KiB
193 lines
5.5 KiB
import React, { Component } from 'react' |
|
import { Link, Route, Switch } from 'react-router-dom' |
|
import { connect } from 'react-redux' |
|
import styled from 'styled-components' |
|
|
|
import { logout } from '../utils/Auth' |
|
import RouteList from './RouteList' |
|
import RouteDetail from './RouteDetail' |
|
import StopList from './StopList' |
|
import StopForm from './StopForm' |
|
import RouteForm from './RouteForm' |
|
import Breadcrumb from './Breadcrumb' |
|
import { polygonReset } from '../actions' |
|
import store from '../store' |
|
|
|
const StyledLink = styled(Link)` |
|
&[data-active] { |
|
color: red; |
|
} |
|
` |
|
|
|
const StyledFloatPane = styled.div` |
|
min-width: 300px; |
|
height: 100%; |
|
width: 25vw; |
|
z-index: 30; |
|
background: #fefefefe; |
|
border-radius: 0 5px 5px 0; |
|
display: flex; |
|
flex-direction: column; |
|
position: fixed; |
|
left: ${props => props.hidePane ? '-500px' : 0}; |
|
top: 0px; |
|
` |
|
|
|
const StyledLRPaddingNav = styled.nav` |
|
padding-right: 10px; |
|
padding-left: 0; |
|
margin-bottom: 5px !important; |
|
min-height: 44px; |
|
` |
|
|
|
const StyledPaneToggler = styled.div` |
|
width: 30px |
|
height: 40px; |
|
background: #fefefebb; |
|
color: #209cee; |
|
position: fixed; |
|
text-align: center; |
|
padding-top: 10px; |
|
left: ${props => props.hidePane ? 0 : '25vw'}; |
|
top: 30px; |
|
border-radius: 0 5px 5px 0; |
|
|
|
@media (max-width: 1200px) { |
|
left: ${props => props.hidePane ? 0 : '300px'}; |
|
} |
|
` |
|
|
|
const StyledScrollY = styled.div` |
|
flex-grow: 1; |
|
overflow: auto; |
|
padding-bottom: 5rem; |
|
` |
|
|
|
const SmallMuted = styled.p` |
|
font-size: 0.85rem; |
|
color: #888; |
|
clear: both; |
|
` |
|
|
|
const SimpleAgencyList = (props) => ( |
|
<nav className="panel"> |
|
<p className="panel-heading"> |
|
Agency |
|
</p> |
|
<p className="panel-tabs"> |
|
<Link className="link is-info" to={`/agency/new`}> |
|
<i className="fas fa-plus" /> New agency |
|
</Link> |
|
</p> |
|
{props.agencies.map(ele => ( |
|
<Link key={ele.agency_id} className="panel-block" to={`/map/${ele.agency_id}`}> |
|
<div> |
|
{ele.name} |
|
<br /> |
|
<SmallMuted>{ele.agency_id}</SmallMuted> |
|
</div> |
|
</Link>))} |
|
</nav> |
|
) |
|
|
|
|
|
|
|
class FloatPane extends Component { |
|
|
|
state = { hidePane: false, breadcrumb: {} } |
|
|
|
renderTopLevel(loggedIn) { |
|
return ( |
|
<StyledLRPaddingNav className="level is-mobile"> |
|
<div className="level-left"> |
|
<StyledLink to="/" className="navbar-item"> |
|
<img src="https://static.10ninox.com/goth-rect-640x160.svg" alt="GoTH" width="112" height="28" /> |
|
</StyledLink> |
|
</div> |
|
<div className="level-right"> |
|
<a className="button is-small is-primary" |
|
onClick={() => store.dispatch(polygonReset())}> |
|
<span className="icon"> |
|
<i className="fas fa-sign-out-alt"></i> |
|
</span> |
|
<span>Clear PG</span> |
|
</a> |
|
{loggedIn && |
|
<a className="button is-small is-outlined" |
|
onClick={() => logout()}> |
|
<span className="icon"> |
|
<i className="fas fa-sign-out-alt"></i> |
|
</span> |
|
<span>Logout</span> |
|
</a> |
|
} |
|
{!loggedIn && |
|
<Link className="button is-small is-outlined is-info" to='/login'> |
|
<span className="icon"> |
|
<i className="fas fa-sign-in-alt"></i> |
|
</span> |
|
<span>Sign in</span> |
|
</Link> |
|
} |
|
</div> |
|
</StyledLRPaddingNav> |
|
) |
|
} |
|
|
|
togglePane() { |
|
this.setState({ hidePane: !this.state.hidePane }) |
|
} |
|
|
|
handleChildMatchParams(params) { |
|
this.setState({ breadcrumb: params }) |
|
} |
|
|
|
render () { |
|
const { loggedIn, agency } = this.props |
|
const { hidePane } = this.state |
|
const { results } = agency |
|
|
|
return ( |
|
<StyledFloatPane hidePane={hidePane}> |
|
<StyledPaneToggler hidePane={hidePane} onClick={this.togglePane.bind(this)}> |
|
<i className='fas fa-align-justify' /> |
|
</StyledPaneToggler> |
|
{this.renderTopLevel(loggedIn)} |
|
<Breadcrumb {...this.state.breadcrumb} /> |
|
<StyledScrollY> |
|
<Switch> |
|
<Route exact path={`/map/stop/new`} render={(props) => ( |
|
<StopForm {...props} |
|
updateBreadcrumb={this.handleChildMatchParams.bind(this)} />)} /> |
|
<Route exact path={`/map/stop/:stopId`} render={(props) => ( |
|
<StopForm {...props} |
|
updateBreadcrumb={this.handleChildMatchParams.bind(this)} />)} /> |
|
<Route exact path={`/map/stop`} component={StopList} /> |
|
<Route exact path={`/map/:agencyId/route/new`} render={(props) => ( |
|
<RouteForm {...props} |
|
updateBreadcrumb={this.handleChildMatchParams.bind(this)} />)} /> |
|
<Route exact path={`/map/:agencyId/route/:routeId/edit`} render={(props) => ( |
|
<RouteForm {...props} |
|
updateBreadcrumb={this.handleChildMatchParams.bind(this)}/>)} /> |
|
<Route exact path={`/map/:agencyId/route/:routeId/:routeParams?`} render={(props) => ( |
|
<RouteDetail {...props} |
|
updateBreadcrumb={this.handleChildMatchParams.bind(this)} />)} /> |
|
<Route exact path={`/map/:agencyId`} render={(props) => ( |
|
<RouteList {...props} |
|
updateBreadcrumb={this.handleChildMatchParams.bind(this)} />)} /> |
|
</Switch> |
|
<Route exact path={`/map`} render={(props) => ( |
|
<SimpleAgencyList agencies={results} {...props} />)} /> |
|
</StyledScrollY> |
|
|
|
</StyledFloatPane> |
|
) |
|
} |
|
} |
|
|
|
const mapStateToProps = state => ({ |
|
agency: state.agency, |
|
}) |
|
export default connect( |
|
mapStateToProps |
|
)(FloatPane)
|
|
|