Skip to content

Commit 161b007

Browse files
authored
Merge pull request #1171 from StoDevX/just-report-a-problem
Add a Report-a-Problem screen for Building Hours
2 parents d98d48d + 7432a5e commit 161b007

File tree

11 files changed

+633
-2
lines changed

11 files changed

+633
-2
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
"react-native-button": "1.8.2",
7373
"react-native-communications": "2.2.1",
7474
"react-native-custom-tabs": "0.1.4",
75+
"react-native-datepicker": "1.5.1",
7576
"react-native-device-info": "0.10.2",
7677
"react-native-google-analytics-bridge": "5.0.1",
7778
"react-native-keychain": "1.2.0",

source/navigation.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import JobDetailView from './views/sis/student-work/detail'
1717
import {
1818
BuildingHoursView,
1919
BuildingHoursDetailView,
20+
BuildingHoursProblemReportView,
21+
BuildingHoursScheduleEditorView,
2022
} from './views/building-hours'
2123
import TransportationView from './views/transportation'
2224
import SettingsView from './views/settings'
@@ -34,6 +36,8 @@ export const AppNavigator = StackNavigator(
3436
HomeView: {screen: HomeView},
3537
BuildingHoursDetailView: {screen: BuildingHoursDetailView},
3638
BuildingHoursView: {screen: BuildingHoursView},
39+
BuildingHoursProblemReportView: {screen: BuildingHoursProblemReportView},
40+
BuildingHoursScheduleEditorView: {screen: BuildingHoursScheduleEditorView},
3741
CalendarView: {screen: CalendarView},
3842
ContactsView: {screen: ContactsView},
3943
CreditsView: {screen: CreditsView},

source/views/building-hours/detail/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ export class BuildingHoursDetailView extends React.PureComponent {
4141
this.setState({now: moment.tz(CENTRAL_TZ)})
4242
}
4343

44+
reportProblem = () => {
45+
this.props.navigation.navigate('BuildingHoursProblemReportView', {
46+
initialBuilding: this.props.navigation.state.params.building,
47+
})
48+
}
49+
4450
render() {
4551
const info = this.props.navigation.state.params.building
4652
const {now} = this.state

source/views/building-hours/detail/schedule-table.ios.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ export class ScheduleTable extends React.PureComponent {
2323

2424
return (
2525
<TableView>
26+
<Section>
27+
<Cell
28+
accessory="DisclosureIndicator"
29+
title="Suggest an Edit"
30+
onPress={onProblemReport}
31+
/>
32+
</Section>
33+
2634
{schedules.map(set =>
2735
<Section
2836
key={set.title}

source/views/building-hours/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@
22

33
export {BuildingHoursView} from './stateful-list'
44
export {BuildingHoursDetailView} from './detail'
5+
export {
6+
BuildingHoursProblemReportView,
7+
BuildingHoursScheduleEditorView,
8+
} from './report'
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// @flow
2+
3+
export const blankSchedule = () => ({days: [], from: '9:00am', to: '5:00pm'})

source/views/building-hours/lib/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ export {formatBuildingTimes} from './format-times'
77
export {summarizeDays} from './summarize-days'
88
export {isScheduleOpenAtMoment} from './is-schedule-open'
99
export {getDayOfWeek} from './get-day-of-week'
10+
export {parseHours} from './parse-hours'
11+
export {blankSchedule} from './blank-schedule'
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
/**
2+
* @flow
3+
*
4+
* An editor for individual building schedules.
5+
*/
6+
7+
import React from 'react'
8+
import xor from 'lodash/xor'
9+
import fromPairs from 'lodash/fromPairs'
10+
import {ScrollView, Text, StyleSheet} from 'react-native'
11+
import moment from 'moment-timezone'
12+
import {TableView, Section, Cell} from 'react-native-tableview-simple'
13+
import type {SingleBuildingScheduleType, DayOfWeekEnumType} from '../types'
14+
import {Row} from '../../components/layout'
15+
import type {TopLevelViewPropsType} from '../../types'
16+
import {parseHours, blankSchedule} from '../lib'
17+
import * as c from '../../components/colors'
18+
import DatePicker from 'react-native-datepicker'
19+
import {Touchable} from '../../components/touchable'
20+
import {DeleteButtonCell} from '../../components/cells/delete-button'
21+
22+
export class BuildingHoursScheduleEditorView extends React.PureComponent {
23+
static navigationOptions = {
24+
title: 'Edit Schedule',
25+
}
26+
27+
state: {
28+
set: ?SingleBuildingScheduleType,
29+
} = {
30+
set: this.props.navigation.state.params.initialSet,
31+
}
32+
33+
props: TopLevelViewPropsType & {
34+
navigation: {
35+
state: {
36+
params: {
37+
set: SingleBuildingScheduleType,
38+
onEditSet: (set: SingleBuildingScheduleType) => any,
39+
onDeleteSet: () => any,
40+
},
41+
},
42+
},
43+
}
44+
45+
delete = () => {
46+
this.props.navigation.state.params.onDeleteSet()
47+
this.props.navigation.goBack()
48+
}
49+
50+
onChangeDays = (newDays: DayOfWeekEnumType[]) => {
51+
this.setState(
52+
state => ({...state, set: {...state.set, days: newDays}}),
53+
() => this.props.navigation.state.params.onEditSet(this.state.set),
54+
)
55+
}
56+
57+
onChangeOpen = (newDate: moment) => {
58+
this.setState(
59+
state => ({...state, set: {...state.set, from: newDate.format('h:mma')}}),
60+
() => this.props.navigation.state.params.onEditSet(this.state.set),
61+
)
62+
}
63+
64+
onChangeClose = (newDate: moment) => {
65+
this.setState(
66+
state => ({...state, set: {...state.set, to: newDate.format('h:mma')}}),
67+
() => this.props.navigation.state.params.onEditSet(this.state.set),
68+
)
69+
}
70+
71+
render() {
72+
const set = this.state.set || blankSchedule()
73+
74+
const {open, close} = parseHours(set, moment())
75+
76+
return (
77+
<ScrollView>
78+
<TableView>
79+
<Section header="DAYS">
80+
<WeekToggles days={set.days} onChangeDays={this.onChangeDays} />
81+
</Section>
82+
83+
<Section header="TIMES">
84+
<DatePickerCell
85+
title="Open"
86+
date={open}
87+
onChange={this.onChangeOpen}
88+
/>
89+
<DatePickerCell
90+
title="Close"
91+
date={close}
92+
onChange={this.onChangeClose}
93+
/>
94+
</Section>
95+
96+
<Section>
97+
<DeleteButtonCell title="Delete Hours" onPress={this.delete} />
98+
</Section>
99+
</TableView>
100+
</ScrollView>
101+
)
102+
}
103+
}
104+
105+
class WeekToggles extends React.PureComponent {
106+
props: {days: DayOfWeekEnumType[], onChangeDays: (DayOfWeekEnumType[]) => any}
107+
108+
toggleDay = day => {
109+
this.props.onChangeDays(xor(this.props.days, [day]))
110+
}
111+
112+
render() {
113+
const allDays = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su']
114+
115+
return (
116+
<Row justifyContent="center">
117+
{allDays.map((day, i) =>
118+
<ToggleButton
119+
key={day}
120+
text={day}
121+
active={this.props.days.includes(day)}
122+
onPress={this.toggleDay}
123+
style={i === allDays.length - 1 && styles.finalCell}
124+
/>,
125+
)}
126+
</Row>
127+
)
128+
}
129+
}
130+
131+
class ToggleButton extends React.PureComponent {
132+
props: {
133+
active: boolean,
134+
text: string,
135+
onPress: (newState: string) => any,
136+
style?: any,
137+
}
138+
139+
onPress = () => this.props.onPress(this.props.text)
140+
141+
render() {
142+
const {text, style, active} = this.props
143+
return (
144+
<Touchable
145+
highlight={false}
146+
containerStyle={[style, styles.dayWrapper, active && styles.activeDay]}
147+
onPress={this.onPress}
148+
>
149+
<Text style={[styles.dayText, active && styles.activeDayText]}>
150+
{text}
151+
</Text>
152+
</Touchable>
153+
)
154+
}
155+
}
156+
157+
class DatePickerCell extends React.PureComponent {
158+
props: {
159+
date: moment,
160+
title: string,
161+
onChange?: (date: moment) => any,
162+
_ref?: (ref: any) => any,
163+
}
164+
165+
_picker: any
166+
openPicker = () => {} //this._picker.onPressDate()
167+
168+
setRef = (ref: any) => {
169+
this._picker = ref
170+
this.props._ref && this.props._ref(ref)
171+
}
172+
173+
onChange = (newDate: moment) => {
174+
console.log(newDate)
175+
this.props.onChange && this.props.onChange(newDate)
176+
}
177+
178+
render() {
179+
const {date, title} = this.props
180+
const accessory = (
181+
<Date ref={this.setRef} date={date.toDate()} onChange={this.onChange} />
182+
)
183+
184+
return (
185+
<Cell
186+
title={title}
187+
cellStyle="RightDetail"
188+
cellAccessoryView={accessory}
189+
onPress={this.openPicker}
190+
/>
191+
)
192+
}
193+
}
194+
195+
const Date = ({date, onChange}) => {
196+
const format = 'h:mma'
197+
198+
const callback = (newDateString: string) => {
199+
const oldMoment = moment(date)
200+
const newMoment = moment(newDateString, format)
201+
202+
oldMoment.hours(newMoment.hours())
203+
oldMoment.minutes(newMoment.minutes())
204+
205+
onChange(oldMoment)
206+
}
207+
208+
return (
209+
<DatePicker
210+
date={date}
211+
style={styles.datePicker}
212+
mode="time"
213+
format={format}
214+
is24Hour={false}
215+
confirmBtnText="Confirm"
216+
cancelBtnText="Cancel"
217+
showIcon={false}
218+
onDateChange={callback}
219+
customStyles={{
220+
dateInput: styles.datePickerInput,
221+
dateText: styles.datePickerText,
222+
}}
223+
/>
224+
)
225+
}
226+
227+
const styles = StyleSheet.create({
228+
dayWrapper: {
229+
flex: 1,
230+
alignItems: 'center',
231+
paddingVertical: 10,
232+
paddingHorizontal: 2,
233+
backgroundColor: c.white,
234+
borderRightWidth: StyleSheet.hairlineWidth,
235+
borderRightColor: c.iosSeparator,
236+
},
237+
finalCell: {
238+
borderRightWidth: 0,
239+
},
240+
activeDay: {
241+
backgroundColor: c.brickRed,
242+
},
243+
dayText: {
244+
fontSize: 16,
245+
},
246+
activeDayText: {
247+
color: c.white,
248+
},
249+
datePicker: {
250+
width: null,
251+
},
252+
datePickerInput: {
253+
flex: 0,
254+
borderWidth: 0,
255+
},
256+
datePickerText: {
257+
color: c.iosDisabledText,
258+
fontSize: 16,
259+
},
260+
})
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// @flow
2+
3+
export {BuildingHoursScheduleEditorView} from './editor'
4+
export {BuildingHoursProblemReportView} from './overview'

0 commit comments

Comments
 (0)