Skip to content

Commit 870f3c4

Browse files
author
David Emory
committed
feat(form): New mobile form layout, including date/time preview & modal components
1 parent da8d9ad commit 870f3c4

File tree

8 files changed

+259
-73
lines changed

8 files changed

+259
-73
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// import necessary React/Redux libraries
2+
import React, { Component, PropTypes } from 'react'
3+
import { connect } from 'react-redux'
4+
import {DateTimeSelector, setDepart, setDate, setTime} from 'otp-react-redux'
5+
import { Button, ButtonGroup } from 'react-bootstrap'
6+
7+
class DateTimeModal extends Component {
8+
static propTypes = {
9+
setDepart: PropTypes.func
10+
}
11+
12+
constructor (props) {
13+
super(props)
14+
this.state = { activePanel: 'ITIN' }
15+
}
16+
17+
render () {
18+
const { activePanel } = this.state
19+
20+
const panels = [
21+
{
22+
key: 'ITIN',
23+
text: 'Exact Time',
24+
component: <DateTimeSelector />
25+
}, {
26+
key: 'PROFILE',
27+
text: 'Time Window',
28+
component: <DateTimeSelector profile />
29+
}
30+
]
31+
32+
return (
33+
<div className='date-time-modal'>
34+
<div className='button-row'>
35+
<ButtonGroup justified>
36+
{panels.map(panel => {
37+
return (
38+
<ButtonGroup key={panel.key}>
39+
<Button
40+
className={panel.key === activePanel ? 'selected' : ''}
41+
onClick={() => this.setState({ activePanel: panel.key })}
42+
>{panel.text}</Button>
43+
</ButtonGroup>
44+
)
45+
})}
46+
</ButtonGroup>
47+
</div>
48+
<div className='main-panel'>
49+
{panels.find(p => p.key === activePanel).component}
50+
</div>
51+
</div>
52+
)
53+
}
54+
}
55+
56+
const mapStateToProps = (state, ownProps) => {
57+
const {departArrive, date, time} = state.otp.currentQuery
58+
return {
59+
config: state.otp.config,
60+
departArrive,
61+
date,
62+
time
63+
}
64+
}
65+
66+
const mapDispatchToProps = {
67+
setDepart,
68+
setDate,
69+
setTime
70+
}
71+
72+
export default connect(mapStateToProps, mapDispatchToProps)(DateTimeModal)
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React, { Component, PropTypes } from 'react'
2+
import { connect } from 'react-redux'
3+
import { Button } from 'react-bootstrap'
4+
5+
class DateTimePreview extends Component {
6+
static propTypes = {
7+
date: PropTypes.string,
8+
departArrive: PropTypes.string,
9+
time: PropTypes.string,
10+
onClick: PropTypes.func
11+
}
12+
13+
render () {
14+
const { date, time, departArrive } = this.props
15+
16+
let timeStr
17+
if (departArrive === 'NOW') timeStr = 'Leave now'
18+
else if (departArrive === 'ARRIVE') timeStr = 'Arrive ' + time
19+
else if (departArrive === 'DEPART') timeStr = 'Depart ' + time
20+
21+
return (
22+
<div className='date-time-preview'>
23+
<div className='details'>
24+
<i className='fa fa-calendar' /> {date}
25+
<br />
26+
<i className='fa fa-clock-o' /> {timeStr}
27+
</div>
28+
<div>
29+
<Button className='change-button' onClick={this.props.onClick}>
30+
Change
31+
</Button>
32+
</div>
33+
</div>
34+
)
35+
}
36+
}
37+
38+
const mapStateToProps = (state, ownProps) => {
39+
const {departArrive, date, time} = state.otp.currentQuery
40+
return {
41+
config: state.otp.config,
42+
departArrive,
43+
date,
44+
time
45+
}
46+
}
47+
48+
const mapDispatchToProps = {
49+
}
50+
51+
export default connect(mapStateToProps, mapDispatchToProps)(DateTimePreview)

lib/components/form/date-time-selector.js

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,87 @@ class DateTimeSelector extends Component {
1313
time: PropTypes.string,
1414
location: PropTypes.object,
1515
label: PropTypes.string,
16+
profile: PropTypes.bool,
1617
setDate: PropTypes.func,
1718
setDepart: PropTypes.func,
1819
setLocation: PropTypes.func,
1920
setTime: PropTypes.func,
2021
type: PropTypes.string // replace with locationType?
2122
}
23+
2224
constructor (props) {
2325
super(props)
2426
this.state = {
2527
dateFocused: false
2628
}
2729
}
30+
2831
_onDepartChange = (evt) => {
2932
console.log(evt.target.value)
3033
this.props.setDepart(evt.target.value)
3134
}
35+
3236
_onDateChange = (evt) => {
3337
console.log(evt.target.value)
3438
this.props.setDate(evt.target.value)
3539
}
40+
3641
_onTimeChange = (evt) => {
3742
console.log(evt.target.value)
3843
this.props.setTime(evt.target.value)
3944
}
45+
4046
render () {
4147
const { departArrive, date, time } = this.props
4248
const options = ['NOW', 'DEPART', 'ARRIVE']
4349
// TODO: choose date / time selectors (currently Chrome optimized)
50+
51+
if (this.props.profile) {
52+
const dowOptions = ['WEEKDAY', 'SATURDAY', 'SUNDAY']
53+
return (
54+
<Form>
55+
<FormGroup style={{marginBottom: '15px'}} className='date-time-selector'>
56+
<Row>
57+
<Col xs={12}>
58+
<FormControl
59+
componentClass='select'
60+
style={{width: '100%'}}
61+
>
62+
{dowOptions.map((o, i) => (
63+
<option key={i} value={o}>{o}</option>
64+
))}
65+
</FormControl>
66+
</Col>
67+
</Row>
68+
<Row style={{ marginTop: 20 }}>
69+
<Col xs={5}>
70+
<FormControl
71+
className='time-selector'
72+
type='time'
73+
value='07:00'
74+
style={{width: '100%'}}
75+
/>
76+
</Col>
77+
<Col xs={2}>TO</Col>
78+
<Col xs={5}>
79+
<FormControl
80+
className='time-selector'
81+
type='time'
82+
value='09:00'
83+
style={{width: '100%'}}
84+
/>
85+
</Col>
86+
</Row>
87+
</FormGroup>
88+
</Form>
89+
)
90+
}
91+
4492
return (
4593
<Form>
4694
<FormGroup style={{marginBottom: '15px'}} className='date-time-selector'>
4795
<Row>
48-
<Col xs={6}>
96+
<Col xs={12}>
4997
<FormControl
5098
componentClass='select'
5199
value={departArrive}
@@ -57,9 +105,8 @@ class DateTimeSelector extends Component {
57105
))}
58106
</FormControl>
59107
</Col>
60-
<Col>{ }</Col>
61108
</Row>
62-
<Row style={{ marginTop: 10 }}>
109+
<Row style={{ marginTop: 20 }}>
63110
<Col xs={6}>
64111
<FormControl
65112
className='date-selector'

lib/components/form/form.css

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@
2020
box-shadow: none;
2121
}
2222

23+
.otp .location-field .location-option .route {
24+
background-color: gray;
25+
color: white;
26+
padding: 2px 3px 0px;
27+
margin-right: 5px;
28+
}
29+
2330
/* Settings Bar */
2431

2532
.otp .settings-bar {
@@ -30,15 +37,19 @@
3037
font-size: 14px;
3138
}
3239

40+
.otp .settings-bar.compressed .selected-modes {
41+
text-align: center;
42+
}
43+
3344
.otp .settings-bar .selected-modes .some-selected .mode-icon {
3445
display: inline-block;
3546
margin-right: 5px;
3647
width: 16px;
3748
height: 16px;
38-
fill: white;
49+
fill: black;
3950
}
4051

41-
.otp .settings-bar .button-container {
52+
.otp .settings-bar.wide .button-container {
4253
float: right;
4354
}
4455

0 commit comments

Comments
 (0)