1+ import memoize from 'lodash.memoize'
2+ import moment from 'moment'
13import React , { Component } from 'react'
2- import { Badge } from 'react-bootstrap'
4+ import { Badge , Button } from 'react-bootstrap'
35import { connect } from 'react-redux'
46
57import * as fieldTripActions from '../../actions/field-trip'
6- import DraggableWindow from './draggable-window'
78import Icon from '../narrative/icon'
89import Loading from '../narrative/loading'
9- import { FieldTripRecordButton , WindowHeader } from './styled'
1010import { getVisibleRequests , TABS } from '../../util/call-taker'
1111import { FETCH_STATUS } from '../../util/constants'
1212
13+ import { FieldTripRecordButton , WindowHeader } from './styled'
14+ import DraggableWindow from './draggable-window'
15+
1316/**
1417 * Displays a searchable list of field trip requests in a draggable window.
1518 */
1619class FieldTripList extends Component {
20+ constructor ( props ) {
21+ super ( props )
22+ this . state = {
23+ date : moment ( ) . startOf ( 'day' ) . format ( 'YYYY-MM-DD' )
24+ }
25+ }
1726 _onClickFieldTrip = ( request ) => {
1827 const { callTaker, fetchFieldTripDetails, setActiveFieldTrip} = this . props
1928 if ( request . id === callTaker . fieldTrip . activeId ) {
@@ -30,6 +39,12 @@ class FieldTripList extends Component {
3039 this . props . setActiveFieldTrip ( null )
3140 }
3241
42+ _getReportUrl = ( ) => {
43+ const { date} = this . state
44+ const [ year , month , day ] = date . split ( '-' )
45+ return `${ this . props . datastoreUrl } /fieldtrip/opsReport?month=${ month } &day=${ day } &year=${ year } `
46+ }
47+
3348 /**
3449 * Change search input selectively. This is to prevent excessive rendering
3550 * each time the search input changes (on TriMet's production instance there
@@ -51,13 +66,40 @@ class FieldTripList extends Component {
5166 this . props . setFieldTripFilter ( { tab : e . currentTarget . name } )
5267 }
5368
69+ _updateReportDate = evt => this . setState ( { date : evt . target . value } )
70+
5471 render ( ) {
5572 const { callTaker, style, toggleFieldTrips, visibleRequests} = this . props
5673 const { fieldTrip} = callTaker
5774 const { activeId, filter} = fieldTrip
5875 const { search} = filter
76+ const { date} = this . state
5977 return (
6078 < DraggableWindow
79+ footer = {
80+ < >
81+ < input
82+ className = 'datetime-slim'
83+ onChange = { this . _updateReportDate }
84+ style = { {
85+ border : 'none' ,
86+ fontSize : '14px' ,
87+ lineHeight : '1em' ,
88+ outline : 'none' ,
89+ width : '106px'
90+ } }
91+ type = 'date'
92+ value = { date }
93+ />
94+ < Button
95+ bsSize = 'xsmall'
96+ href = { this . _getReportUrl ( ) }
97+ target = '_blank'
98+ >
99+ View report
100+ </ Button >
101+ </ >
102+ }
61103 header = {
62104 < >
63105 < WindowHeader >
@@ -83,27 +125,14 @@ class FieldTripList extends Component {
83125 />
84126 </ span >
85127 </ WindowHeader >
86- { TABS . map ( tab => {
87- const active = tab . id === filter . tab
88- const style = {
89- backgroundColor : active ? 'navy' : undefined ,
90- borderRadius : 5 ,
91- color : active ? 'white' : undefined ,
92- padding : '2px 3px'
93- }
94- const requestCount = fieldTrip . requests . data . filter ( tab . filter ) . length
95- return (
96- < button
97- className = 'clear-button-formatting'
98- key = { tab . id }
99- name = { tab . id }
100- onClick = { this . _onTabChange }
101- style = { style }
102- >
103- { tab . label } < Badge > { requestCount } </ Badge >
104- </ button >
105- )
106- } ) }
128+ { TABS . map ( tab =>
129+ < Tab
130+ data = { fieldTrip . requests . data }
131+ filter = { filter }
132+ key = { tab . id }
133+ onClick = { this . _onTabChange }
134+ tab = { tab } />
135+ ) }
107136 </ >
108137 }
109138 onClickClose = { toggleFieldTrips }
@@ -127,6 +156,32 @@ class FieldTripList extends Component {
127156 }
128157}
129158
159+ class Tab extends Component {
160+ getCount = memoize ( ( data , filter ) => data . filter ( filter ) . length )
161+
162+ render ( ) {
163+ const { data, filter, onClick, tab} = this . props
164+ const active = tab . id === filter . tab
165+ const style = {
166+ backgroundColor : active ? 'navy' : undefined ,
167+ borderRadius : 5 ,
168+ color : active ? 'white' : undefined ,
169+ padding : '2px 3px'
170+ }
171+ return (
172+ < button
173+ className = 'clear-button-formatting'
174+ key = { tab . id }
175+ name = { tab . id }
176+ onClick = { onClick }
177+ style = { style }
178+ >
179+ { tab . label } < Badge > { this . getCount ( data , tab . filter ) } </ Badge >
180+ </ button >
181+ )
182+ }
183+ }
184+
130185class FieldTripRequestRecord extends Component {
131186 _onClick = ( ) => {
132187 const { onClick, request} = this . props
@@ -151,8 +206,10 @@ class FieldTripRequestRecord extends Component {
151206 schoolName,
152207 startLocation,
153208 teacherName,
154- timeStamp
209+ timeStamp,
210+ travelDate
155211 } = request
212+ const formattedDate = travelDate . split ( ' ' ) . splice ( 0 , 3 ) . join ( ' ' )
156213 return (
157214 < li
158215 className = 'list-unstyled'
@@ -174,11 +231,11 @@ class FieldTripRequestRecord extends Component {
174231 { this . _getStatusIcon ( outboundTripStatus ) } Outbound
175232 </ span >
176233 </ span >
177- < span style = { { display : 'block' } } >
234+ < span style = { { display : 'block' , fontSize : '.9em' } } >
178235 Submitted by { teacherName } on { timeStamp }
179236 </ span >
180- < span style = { { display : 'block' } } >
181- { startLocation } to { endLocation }
237+ < span style = { { display : 'block' , fontSize : '.9em' } } >
238+ { startLocation } to { endLocation } on < strong > { formattedDate } </ strong >
182239 </ span >
183240 </ FieldTripRecordButton >
184241 </ li >
@@ -190,6 +247,7 @@ const mapStateToProps = (state, ownProps) => {
190247 return {
191248 callTaker : state . callTaker ,
192249 currentQuery : state . otp . currentQuery ,
250+ datastoreUrl : state . otp . config . datastoreUrl ,
193251 searches : state . otp . searches ,
194252 visibleRequests : getVisibleRequests ( state )
195253 }
0 commit comments