sipp11
6 years ago
16 changed files with 517 additions and 49 deletions
@ -0,0 +1,67 @@
|
||||
import { RSAA } from 'redux-api-middleware' |
||||
|
||||
import * as types from '../constants/ActionTypes' |
||||
import { RSAAHeaders } from '../utils/ApiClient' |
||||
import { API_URL } from '../constants/Api' |
||||
|
||||
|
||||
export const getFrequency = (query) => ({ |
||||
[RSAA]: { |
||||
endpoint: `${API_URL}/frequency/?${query || ''}`, |
||||
method: 'GET', |
||||
headers: RSAAHeaders, |
||||
bailout: (state) => state.frequency.fetching || state.frequency.query === query, |
||||
types: [ |
||||
{ |
||||
type: types.FREQUENCY_REQUEST, |
||||
meta: { query: query }, |
||||
}, |
||||
types.FREQUENCY_SUCCESS, |
||||
types.FREQUENCY_FAILURE, |
||||
] |
||||
} |
||||
}) |
||||
|
||||
export const updateFrequency = (id, body) => ({ |
||||
[RSAA]: { |
||||
endpoint: `${API_URL}/frequency/${id}/`, |
||||
body: JSON.stringify(body), |
||||
method: 'PATCH', |
||||
headers: RSAAHeaders, |
||||
types: [ |
||||
types.FREQUENCY_REQUEST, |
||||
types.FREQUENCY_UPDATE, |
||||
types.FREQUENCY_FAILURE, |
||||
] |
||||
} |
||||
}) |
||||
|
||||
export const createFrequency = (body) => ({ |
||||
[RSAA]: { |
||||
endpoint: `${API_URL}/frequency/`, |
||||
body: JSON.stringify(body), |
||||
method: 'POST', |
||||
headers: RSAAHeaders, |
||||
types: [ |
||||
types.FREQUENCY_REQUEST, |
||||
types.FREQUENCY_CREATE, |
||||
types.FREQUENCY_FAILURE, |
||||
] |
||||
} |
||||
}) |
||||
|
||||
export const deleteFrequency = (id) => ({ |
||||
[RSAA]: { |
||||
endpoint: `${API_URL}/frequency/${id}/`, |
||||
method: 'DELETE', |
||||
headers: RSAAHeaders, |
||||
types: [ |
||||
types.FREQUENCY_REQUEST, |
||||
{ |
||||
type: types.FREQUENCY_DELETE, |
||||
meta: { id } |
||||
}, |
||||
types.FREQUENCY_FAILURE, |
||||
] |
||||
} |
||||
}) |
@ -0,0 +1,126 @@
|
||||
import React, { Component } from 'react' |
||||
import styled from 'styled-components' |
||||
|
||||
import Input from './parts/Input' |
||||
import Select from './parts/Select' |
||||
import { |
||||
updateFrequency, createFrequency, deleteFrequency |
||||
} from '../actions/frequency' |
||||
import store from '../store' |
||||
import { |
||||
ExactTimeChoices |
||||
} from '../constants/choices' |
||||
import { getItemFromList } from '../utils' |
||||
|
||||
const StyleBox = styled.div` |
||||
padding: 5px; |
||||
background: white; |
||||
margin-bottom: 1rem; |
||||
` |
||||
|
||||
class FrequencyForm extends Component { |
||||
|
||||
cancel = null |
||||
state = { |
||||
editMode: false, |
||||
trip: null, |
||||
id: null, |
||||
} |
||||
|
||||
constructor(props) { |
||||
super(props) |
||||
this.handleChange = this.handleChange.bind(this) |
||||
this.handleSubmit = this.handleSubmit.bind(this) |
||||
this.handleDelete = this.handleDelete.bind(this) |
||||
} |
||||
|
||||
handleChange(evt) { |
||||
let updated = {} |
||||
updated[evt.target.name] = evt.target.value |
||||
this.setState(updated) |
||||
} |
||||
|
||||
handleSubmit() { |
||||
const { id } = this.state |
||||
let body = {...this.state } |
||||
delete body.id |
||||
if (id !== null) { |
||||
store.dispatch(updateFrequency(id, body)) |
||||
} else { |
||||
store.dispatch(createFrequency(body)) |
||||
} |
||||
this.props.toggleEditMode() |
||||
} |
||||
|
||||
handleDelete() { |
||||
const { id } = this.state |
||||
store.dispatch(deleteFrequency(id)) |
||||
this.props.toggleEditMode() |
||||
} |
||||
|
||||
static getDerivedStateFromProps(props, state) { |
||||
if (props.item && props.item.id !== null && state.id === null) { |
||||
return props.item |
||||
} else if (props.trip !== undefined) { |
||||
return { trip: props.trip } |
||||
} |
||||
return null |
||||
} |
||||
|
||||
render() { |
||||
const item = this.state |
||||
return ( |
||||
<StyleBox> |
||||
<Input |
||||
label="Start" |
||||
type="text" |
||||
fieldName="start_time" |
||||
value={item.start_time || ''} |
||||
handleChange={this.handleChange} /> |
||||
|
||||
<Input |
||||
label="End" |
||||
type="text" |
||||
fieldName="end_time" |
||||
value={item.end_time || ''} |
||||
handleChange={this.handleChange} /> |
||||
<Input |
||||
label="Headway secs" |
||||
type="text" |
||||
fieldName="headway_secs" |
||||
value={item.headway_secs || ''} |
||||
handleChange={this.handleChange} /> |
||||
|
||||
<Select |
||||
label="Exact Times" |
||||
type="text" |
||||
fieldName="exact_times" |
||||
value={getItemFromList(item.exact_times, ExactTimeChoices, '0')} |
||||
handleChange={this.handleChange} |
||||
choices={ExactTimeChoices} /> |
||||
|
||||
<div className="field is-grouped"> |
||||
<div className="control"> |
||||
<button className="button is-link" |
||||
onClick={this.handleSubmit} |
||||
disabled={false}> |
||||
Save</button> |
||||
</div> |
||||
{item.id !== null && <div className="control"> |
||||
<button className="button is-danger" |
||||
onClick={this.handleDelete} |
||||
disabled={false}> |
||||
DELETE</button> |
||||
</div>} |
||||
{this.props.toggleEditMode && |
||||
<div className="control"> |
||||
<a onClick={() => this.props.toggleEditMode()} className="button is-text">Cancel</a> |
||||
</div>} |
||||
</div> |
||||
</StyleBox> |
||||
) |
||||
} |
||||
|
||||
} |
||||
|
||||
export default FrequencyForm |
@ -0,0 +1,73 @@
|
||||
import React, { Component } from 'react' |
||||
import styled from 'styled-components' |
||||
|
||||
import FrequencyForm from './FrequencyForm' |
||||
import { ExactTimeChoices } from '../constants/choices' |
||||
import { getItemFromList } from '../utils' |
||||
|
||||
const StyledRow = styled.div` |
||||
padding-top: 5px; |
||||
padding-bottom: 5px; |
||||
background: white; |
||||
margin-bottom: 1rem; |
||||
` |
||||
|
||||
class FrequencyOne extends Component { |
||||
|
||||
state = { |
||||
editMode: false |
||||
} |
||||
|
||||
constructor(props) { |
||||
super(props) |
||||
this.toggleEditMode = this.toggleEditMode.bind(this) |
||||
} |
||||
|
||||
toggleEditMode() { |
||||
this.setState({editMode: !this.state.editMode}) |
||||
} |
||||
|
||||
renderReadOnly = (item) => ( |
||||
<StyledRow className="level panel" key={`st-item-${item.id}`}> |
||||
<div className="level-item has-text-centered"> |
||||
<div> |
||||
<p className="heading"> |
||||
<a onClick={() => this.toggleEditMode()}> EDIT</a> |
||||
Start Time</p> |
||||
<p className="title">{item.start_time}</p> |
||||
</div> |
||||
</div> |
||||
<div className="level-item has-text-centered"> |
||||
<div> |
||||
<p className="heading">End Time</p> |
||||
<p className="title">{item.end_time}</p> |
||||
</div> |
||||
</div> |
||||
<div className="level-item has-text-centered"> |
||||
<div> |
||||
<p className="heading">Headway secs</p> |
||||
<p className="title">{item.headway_secs}</p> |
||||
</div> |
||||
</div> |
||||
<div className="level-item has-text-centered"> |
||||
<div> |
||||
<p className="heading">Exact Times</p> |
||||
<p className="title">{getItemFromList(item.exact_times, ExactTimeChoices).value}</p> |
||||
</div> |
||||
</div> |
||||
</StyledRow> |
||||
) |
||||
|
||||
render() { |
||||
const { item, tripId } = this.props |
||||
if (this.state.editMode) |
||||
return <FrequencyForm |
||||
item={item} |
||||
trip={tripId} |
||||
toggleEditMode={this.toggleEditMode} /> |
||||
return this.renderReadOnly(item) |
||||
} |
||||
|
||||
} |
||||
|
||||
export default FrequencyOne |
@ -0,0 +1,88 @@
|
||||
import { |
||||
FREQUENCY_CREATE, FREQUENCY_DELETE, FREQUENCY_UPDATE, |
||||
FREQUENCY_REQUEST, FREQUENCY_SUCCESS, FREQUENCY_FAILURE, |
||||
GEO_POLYGON_RESET, |
||||
} from '../constants/ActionTypes' |
||||
|
||||
|
||||
const frequencyInitState = { |
||||
results: [], |
||||
next: null, |
||||
count: 0, |
||||
fetching: false, |
||||
query: '', |
||||
} |
||||
const frequency = (state = frequencyInitState, action) => { |
||||
switch (action.type) { |
||||
case GEO_POLYGON_RESET: |
||||
return { |
||||
...state, |
||||
fetching: false, |
||||
count: 0, |
||||
next: null, |
||||
query: '', |
||||
results: [], |
||||
} |
||||
case FREQUENCY_REQUEST: |
||||
return { |
||||
...state, |
||||
fetching: true, |
||||
query: action.meta !== undefined ? action.meta.query : state.query, |
||||
} |
||||
case FREQUENCY_SUCCESS: |
||||
const { count, next, prev, results } = action.payload |
||||
return { |
||||
...state, |
||||
fetching: false, |
||||
count, |
||||
next, |
||||
results: [ |
||||
...((prev) ? state.results : []), |
||||
...results, |
||||
] |
||||
} |
||||
case FREQUENCY_UPDATE: |
||||
const { id } = action.payload |
||||
const oldResults = state.results |
||||
const targetInd = oldResults.findIndex(ele => ele.id === id) |
||||
return { |
||||
...state, |
||||
fetching: false, |
||||
results: [ |
||||
...oldResults.slice(0, targetInd), |
||||
action.payload, |
||||
...oldResults.slice(targetInd + 1) |
||||
] |
||||
} |
||||
case FREQUENCY_CREATE: |
||||
return { |
||||
...state, |
||||
fetching: false, |
||||
count: state.count + 1, |
||||
results: [ |
||||
...state.results, |
||||
action.payload, |
||||
] |
||||
} |
||||
case FREQUENCY_DELETE: |
||||
const deleteInd = state.results.findIndex(ele => ele.id === action.meta.id) |
||||
return { |
||||
...state, |
||||
count: state.count - 1, |
||||
fetching: false, |
||||
results: [ |
||||
...state.results.slice(0, deleteInd), |
||||
...state.results.slice(deleteInd + 1) |
||||
] |
||||
} |
||||
case FREQUENCY_FAILURE: |
||||
return { |
||||
...state, |
||||
fetching: false, |
||||
} |
||||
default: |
||||
return state; |
||||
} |
||||
} |
||||
|
||||
export default frequency |
Loading…
Reference in new issue