Browse Source

Service CRUD

* Add message when failing to auth
master
sipp11 7 years ago
parent
commit
1b201a9101
  1. 1
      package.json
  2. 7
      public/index.html
  3. 7
      src/actions/calendar.js
  4. 21
      src/components/AgencyForm.js
  5. 7
      src/components/AgencyItem.js
  6. 73
      src/components/AgencyList.js
  7. 217
      src/components/CalendarForm.js
  8. 112
      src/components/CalendarList.js
  9. 2
      src/components/FareAttrList.js
  10. 5
      src/components/Footer.js
  11. 1
      src/components/Login.js
  12. 30
      src/components/parts/HorizontalCheckbox.js
  13. 30
      src/components/parts/HorizontalDate.js
  14. 21
      src/components/parts/HorizontalInput.js
  15. 10
      src/container/Main.js
  16. 4
      src/container/Public.js
  17. 7
      src/reducers/auth.js
  18. 2
      src/reducers/calendar.js
  19. 22
      src/reducers/fareattr.js
  20. 2
      src/reducers/index.js
  21. 2
      src/store.js

1
package.json

@ -8,6 +8,7 @@
"moment": "^2.22.2", "moment": "^2.22.2",
"react": "^16.4.1", "react": "^16.4.1",
"react-dom": "^16.4.1", "react-dom": "^16.4.1",
"react-flatpickr": "^3.6.4",
"react-redux": "^5.0.7", "react-redux": "^5.0.7",
"react-router-dom": "^4.3.1", "react-router-dom": "^4.3.1",
"react-scripts": "1.1.4", "react-scripts": "1.1.4",

7
public/index.html

@ -8,9 +8,10 @@
manifest.json provides metadata used when your web app is added to the manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/ homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
--> -->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json"> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<link rel="stylesheet" href="https://static.10ninox.com/css/bulma.min.css"> <link rel="stylesheet" href="https://static.10ninox.com/css/bulma.min.css" />
<link rel="stylesheet" href="https://static.10ninox.com/css/bulma-checkradio.min.css" />
<script defer="defer" src="https://use.fontawesome.com/releases/v5.0.7/js/all.js"></script> <script defer="defer" src="https://use.fontawesome.com/releases/v5.0.7/js/all.js"></script>
<!-- <!--
Notice the use of %PUBLIC_URL% in the tags above. Notice the use of %PUBLIC_URL% in the tags above.

7
src/actions/calendar.js

@ -10,12 +10,9 @@ export const getCalendar = (query) => ({
endpoint: `${API_URL}/calendar/?${query || ''}`, endpoint: `${API_URL}/calendar/?${query || ''}`,
method: 'GET', method: 'GET',
headers: RSAAHeaders, headers: RSAAHeaders,
bailout: (state) => state.calendar.fetching || state.calendar.query === query, bailout: (state) => state.calendar.fetching,
types: [ types: [
{ types.CALENDAR_REQUEST,
type: types.CALENDAR_REQUEST,
meta: { query: query },
},
types.CALENDAR_SUCCESS, types.CALENDAR_SUCCESS,
types.CALENDAR_FAILURE, types.CALENDAR_FAILURE,
] ]

21
src/components/AgencyForm.js

@ -3,31 +3,14 @@ import styled from 'styled-components'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { Redirect, Link } from 'react-router-dom' import { Redirect, Link } from 'react-router-dom'
import HorizontalInput from './parts/HorizontalInput'
import { updateAgency, createAgency, deleteAgency } from '../actions'; import { updateAgency, createAgency, deleteAgency } from '../actions';
import store from '../store' import store from '../store'
const StyledAgencyForm = styled.div` const StyledAgencyForm = styled.div`
padding: 1rem; padding: 1rem;
background: #fafafa; background: #fafafa;
`; `
const HorizontalInput = (props) => (
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">{props.label}</label>
</div>
<div className="field-body">
<div className="field">
<p className="control">
<input className="input" type={props.type || 'text'}
name={props.fieldName}
onChange={props.handleChange}
defaultValue={props.value} />
</p>
</div>
</div>
</div>
)
class AgencyForm extends Component { class AgencyForm extends Component {

7
src/components/AgencyItem.js

@ -31,9 +31,7 @@ class AgencyItem extends Component {
return ( return (
<StyledAgencyItem> <StyledAgencyItem>
<h1 className="title"> <h1 className="title">{one.name}&nbsp;&nbsp;</h1>
{one.name}&nbsp;&nbsp;
<Link to={`/agency/${one.agency_id}/edit`} className="button">Edit</Link></h1>
<div className="columns"> <div className="columns">
<div className="column is-3 is-hidden-mobile"> <div className="column is-3 is-hidden-mobile">
<div className="content"> <div className="content">
@ -56,11 +54,12 @@ class AgencyItem extends Component {
</div> </div>
</div> </div>
<div className="column is-9"> <div className="column is-9">
<div className="tabs"> <div className="tabs is-centered">
<ul> <ul>
<li className={`${agencyChild === undefined && "is-active"}`}><Link to={`/agency/${one.agency_id}`}>Overview</Link></li> <li className={`${agencyChild === undefined && "is-active"}`}><Link to={`/agency/${one.agency_id}`}>Overview</Link></li>
<li className={`${agencyChild === 'route' && "is-active"}`}><Link to={`/agency/${one.agency_id}/route`}>Route</Link></li> <li className={`${agencyChild === 'route' && "is-active"}`}><Link to={`/agency/${one.agency_id}/route`}>Route</Link></li>
<li className={`${agencyChild === 'fare-attr' && "is-active"}`}><Link to={`/agency/${one.agency_id}/fare-attr`}>Fare Attributes</Link></li> <li className={`${agencyChild === 'fare-attr' && "is-active"}`}><Link to={`/agency/${one.agency_id}/fare-attr`}>Fare Attributes</Link></li>
<li><Link to={`/agency/${one.agency_id}/edit`}>Edit</Link></li>
</ul> </ul>
</div> </div>
<Route path={`/agency/:agencyId/route/:routeId`} component={RouteList} /> <Route path={`/agency/:agencyId/route/:routeId`} component={RouteList} />

73
src/components/AgencyList.js

@ -6,10 +6,18 @@ import { Link } from 'react-router-dom'
import { getAgency } from '../actions' import { getAgency } from '../actions'
import store from '../store' import store from '../store'
// const StyledAgencyList = styled.section` const StyledBox = styled.div`
// padding: 1em; padding: 1rem;
// background: papayawhip; background: #fafafa;
// `; `
const FakeRow = styled.nav`
padding-top: 5px;
padding-bottom: 5px;
background: white;
margin-bottom: 1rem;
`
class AgencyList extends Component { class AgencyList extends Component {
@ -22,13 +30,60 @@ class AgencyList extends Component {
render() { render() {
const { results } = this.props.agency const { results } = this.props.agency
return ( return (
<ul> <StyledBox>
<h1 className="title">Agency</h1>
<div className="columns">
<div className="column is-12">
<nav className="level is-mobile">
<p className="level-item has-text-centered">
<Link className="link is-info" to={`/agency/new`}>
<i className="fas fa-plus" /> New agency
</Link>
</p>
</nav>
{results && Object.keys(results).map(i => ( {results && Object.keys(results).map(i => (
<li key={i}> <FakeRow className="level panel" key={i}>
<Link to={`/agency/${results[i].agency_id}`}>{results[i].agency_id}</Link> <div className="level-item has-text-centered">
</li> <div>
<p className="heading">Agency ID</p>
<p className="title">
<Link to={`/agency/${results[i].agency_id}`}>
{results[i].agency_id}</Link></p>
</div>
</div>
<div className="level-item has-text-centered">
<div>
<p className="heading">Contact</p>
<p className="title">{results[i].url
&& <a href={results[i].url}>web</a>}
{(results[i].url && results[i].email) && <span> / </span>}
{results[i].email
&& <a href={`mailto:${results[i].email}`}>email</a>}</p>
</div>
</div>
<div className="level-item has-text-centered">
<div>
<p className="heading">Language</p>
<p className="title">{results[i].lang || '-'}</p>
</div>
</div>
<div className="level-item has-text-centered">
<div>
<p className="heading">Timezone</p>
<p className="title">{results[i].timezone || '-'}</p>
</div>
</div>
<div className="level-item has-text-centered">
<div>
<p className="heading">Phone</p>
<p className="title">{results[i].phone || '-'}</p>
</div>
</div>
</FakeRow>
))} ))}
</ul> </div>
</div>
</StyledBox>
) )
} }
} }

217
src/components/CalendarForm.js

@ -0,0 +1,217 @@
import React, { Component } from 'react'
import styled from 'styled-components'
import { connect } from 'react-redux'
import { Redirect, Link } from 'react-router-dom'
import { updateCalendar, createCalendar, deleteCalendar } from '../actions/calendar'
import store from '../store'
import HorizontalInput from './parts/HorizontalInput'
import HorizontalDate from './parts/HorizontalDate'
import HorizontalCheckbox from './parts/HorizontalCheckbox'
const StyledCalendarForm = styled.div`
padding: 1rem;
background: #fafafa;
`;
class CalendarForm extends Component {
state = {
id: null,
service_id: "",
start_date: "",
end_date: "",
monday: false,
tuesday: false,
wednesday: false,
thursday: false,
friday: false,
saturday: false,
sunday: false,
}
constructor() {
super()
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
this.handleDelete = this.handleDelete.bind(this)
this.renderForm = this.renderForm.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(updateCalendar(id, body))
} else {
store.dispatch(createCalendar(body))
}
this.setState({justSubmit: true})
}
handleDelete() {
const { id } = this.state
store.dispatch(deleteCalendar(id))
this.setState({justSubmit: true})
}
componentWillMount() {
const { props } = this
const { serviceId } = props.match.params
const { results } = props.calendar
const ones = results.filter(ele => ele.service_id === serviceId)
if (ones.length > 0) {
this.setState(ones[0])
}
}
renderForm() {
const one = this.state
const { fetching } = this.props.calendar
return (
<StyledCalendarForm>
<h1 className="title">{one.name}&nbsp;&nbsp;</h1>
<div className="content">
<HorizontalInput
label="Calendar ID"
type="text"
fieldName="service_id"
value={one.service_id || ''}
handleChange={this.handleChange} />
<HorizontalDate
label="Start Date"
type="text"
fieldName="start_date"
value={one.start_date || ''}
handleChange={this.handleChange} />
<HorizontalDate
key="end_date"
label="End Date"
type="text"
fieldName="end_date"
value={one.end_date || ''}
handleChange={this.handleChange} />
<HorizontalCheckbox
key="Monday"
label="Monday"
type="text"
fieldName="monday"
value={one.monday || false}
handleChange={this.handleChange} />
<HorizontalCheckbox
key="Tuesday"
label="Tuesday"
type="text"
fieldName="tuesday"
value={one.tuesday || false}
handleChange={this.handleChange} />
<HorizontalCheckbox
key="Wednesday"
label="Wednesday"
type="text"
fieldName="wednesday"
value={one.wednesday || false}
handleChange={this.handleChange} />
<HorizontalCheckbox
key="Thursday"
label="Thursday"
type="text"
fieldName="thursday"
value={one.thursday || false}
handleChange={this.handleChange} />
<HorizontalCheckbox
key="Friday"
label="Friday"
type="text"
fieldName="friday"
value={one.friday || false}
handleChange={this.handleChange} />
<HorizontalCheckbox
key="Saturday"
label="Saturday"
type="text"
fieldName="saturday"
value={one.saturday || false}
handleChange={this.handleChange} />
<HorizontalCheckbox
key="Sunday"
label="Sunday"
type="text"
fieldName="sunday"
value={one.sunday || false}
handleChange={this.handleChange} />
</div>
<div className="field is-grouped">
<div className="control">
<button className="button is-link"
onClick={this.handleSubmit}
disabled={fetching}>
Save</button>
</div>
{one.id !== null && <div className="control">
<button className="button is-danger"
onClick={this.handleDelete}
disabled={fetching}>
DELETE</button>
</div>}
<div className="control">
<Link to={`/calendar`} className="button is-text">Cancel</Link>
</div>
</div>
</StyledCalendarForm>
)
}
render () {
const one = this.state
const { fetching } = this.props.calendar
// redirect to view page if no data
const { serviceId } = this.props.match.params
// this is a create form
if (serviceId === undefined) {
if (one.justSubmit === true && !fetching) {
return <Redirect to={`/calendar`} />
}
return this.renderForm()
}
if (one.id === null && serviceId.length > 0)
return <Redirect to={`/calendar`} />
// redirect to calendar list if submitted
if (one.justSubmit === true && !fetching) {
return <Redirect to={`/calendar`} />
}
return this.renderForm()
}
}
const mapStateToProps = state => ({
calendar: state.calendar
})
const connectCalendarFom = connect(
mapStateToProps,
)(CalendarForm)
export default connectCalendarFom

112
src/components/CalendarList.js

@ -0,0 +1,112 @@
import React, { Component } from 'react'
import styled from 'styled-components'
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import { getCalendar } from '../actions/calendar'
import store from '../store'
const StyledBox = styled.div`
padding: 1rem;
background: #fafafa;
`
const GapBox = styled.span`
margin-right: 5px;
color: ${props => props.checked ? 'green' : 'gray'};;
`
const FakeRow = styled.nav`
padding-top: 5px;
padding-bottom: 5px;
background: white;
margin-bottom: 1rem;
`
const CheckboxIcon = (props) => (
<GapBox checked={props.checked}>
{props.checked === true && <span><i className="fas fa-check-square"></i></span>}
{props.checked !== true && <span><i className="fas fa-square"></i></span>}
</GapBox>
)
class CalendarList extends Component {
componentWillMount() {
const { count } = this.props.calendar
if (count === 0)
store.dispatch(getCalendar())
}
render() {
const { results } = this.props.calendar
const { match } = this.props
return (
<StyledBox>
<h1 className="title">Service</h1>
<div className="columns">
<div className="column is-12">
<nav className="level is-mobile">
<p className="level-item has-text-centered">
<Link className="link is-info" to={`${match.url}/new`}>
<i className="fas fa-plus" /> New service
</Link>
</p>
</nav>
{results && Object.keys(results).map(i => (
<FakeRow className="level panel" key={i}>
<div className="level-item has-text-centered">
<div>
<p className="heading">Service ID</p>
<p className="title"><Link to={`${match.url}/${results[i].service_id}`}>{results[i].service_id}</Link></p>
</div>
</div>
<div className="level-item has-text-centered">
<div>
<p className="heading">Start</p>
<p className="title">{results[i].start_date}</p>
</div>
</div>
<div className="level-item has-text-centered">
<div>
<p className="heading">End</p>
<p className="title">{results[i].end_date}</p>
</div>
</div>
<div className="level-item has-text-centered">
<div>
<p className="heading">M T W Th F Sa Su</p>
<p className="title">
<CheckboxIcon disabled={true} checked={results[i].monday} />
<CheckboxIcon disabled={true} checked={results[i].tuesday} />
<CheckboxIcon disabled={true} checked={results[i].wednesday} />
<CheckboxIcon disabled={true} checked={results[i].thursday} />
<CheckboxIcon disabled={true} checked={results[i].friday} />
<CheckboxIcon disabled={true} checked={results[i].saturday} />
<CheckboxIcon disabled={true} checked={results[i].sunday} />
</p>
</div>
</div>
</FakeRow>
))}
</div>
</div>
</StyledBox>
)
}
}
const mapStateToProps = state => ({
calendar: state.calendar
})
const connectCalendarList = connect(
mapStateToProps,
{},
)(CalendarList)
export default styled(connectCalendarList)`
color: palevioletred;
font-weight: bold;
`

2
src/components/FareAttrList.js

@ -28,7 +28,7 @@ class FareAttrList extends Component {
<h3 className="title">Fare Attributes</h3> <h3 className="title">Fare Attributes</h3>
<Spinner show={fareattr.fetching} /> <Spinner show={fareattr.fetching} />
<ul> <ul>
{fareattr.count === 0 && <li>No fare attribute</li>} {fareattr.count === 0 && <li key="nah">No fare attribute</li>}
{fareattr.count > 0 {fareattr.count > 0
&& fareattr.results.map(ele => ( && fareattr.results.map(ele => (
<li key={ele.fare_id}>{ ele.fare_id }</li>) <li key={ele.fare_id}>{ ele.fare_id }</li>)

5
src/components/Footer.js

@ -3,9 +3,8 @@ import React from 'react'
const Footer = () => const Footer = () =>
<footer className="footer"> <footer className="footer">
<div className="content has-text-centered"> <div className="content has-text-centered">
<p> <img src="https://static.10ninox.com/goth-rect-640x160.svg" alt="GoTH" width="168" height="42" />
<strong>Go</strong><sup>TH</sup> {/* <strong>Go</strong><sup>TH</sup> */}
</p>
</div> </div>
</footer> </footer>

1
src/components/Login.js

@ -6,6 +6,7 @@ let goodPassword = null
const Login = (props) => ( const Login = (props) => (
<div> <div>
<h1 className="title">Login</h1> <h1 className="title">Login</h1>
{props.failMessage && <div className="notification is-warning">{props.failMessage}</div>}
<div className="field"> <div className="field">
<label className="label">Email</label> <label className="label">Email</label>
<div className="control has-icons-left has-icons-right"> <div className="control has-icons-left has-icons-right">

30
src/components/parts/HorizontalCheckbox.js

@ -0,0 +1,30 @@
import React from 'react'
const HorizontalInput = (props) => (
<div className="field is-horizontal">
<div className="field-label is-normal">
{/* <label for={`id_${props.fieldName}`} className="label">{props.label}</label> */}
</div>
<div className="field-body">
<div className="field">
<input
className="is-checkradio has-background-color is-info"
id={`id_${props.fieldName}`}
type="checkbox"
name={props.fieldName}
defaultChecked={props.value}
onChange={(evt) => {
let res = {
target: {
name: evt.target.name,
value: evt.target.checked
}
}
return props.handleChange(res)}} />
<label htmlFor={`id_${props.fieldName}`}>{props.label}</label>
</div>
</div>
</div>
)
export default HorizontalInput

30
src/components/parts/HorizontalDate.js

@ -0,0 +1,30 @@
import React from 'react'
import Flatpickr from 'react-flatpickr'
import 'flatpickr/dist/themes/airbnb.css'
const HorizontalDate = (props) => (
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">{props.label}</label>
</div>
<div className="field-body">
<div className="field">
<p className="control">
<Flatpickr
className="input"
defaultValue={props.value}
onChange={(date) => {
let evt = {
target: {
name: props.fieldName,
value: date[0].toISOString('YYYY-MM-DD').slice(0, 10)
}}
return props.handleChange(evt)}} />
</p>
</div>
</div>
</div>
)
export default HorizontalDate

21
src/components/parts/HorizontalInput.js

@ -0,0 +1,21 @@
import React from 'react'
const HorizontalInput = (props) => (
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">{props.label}</label>
</div>
<div className="field-body">
<div className="field">
<p className="control">
<input className="input" type={props.type || 'text'}
name={props.fieldName}
onChange={props.handleChange}
defaultValue={props.value} />
</p>
</div>
</div>
</div>
)
export default HorizontalInput

10
src/container/Main.js

@ -4,8 +4,9 @@ import { Redirect, Route, Switch } from 'react-router-dom'
import { loggedIn } from '../reducers/auth' import { loggedIn } from '../reducers/auth'
import { getAgency } from '../actions' import { getAgency } from '../actions'
import Nav from '../components/Nav' import Nav from '../components/Nav'
import CalendarForm from '../components/CalendarForm'
import CalendarList from '../components/CalendarList'
import AgencyList from '../components/AgencyList' import AgencyList from '../components/AgencyList'
import AgencyItem from '../components/AgencyItem' import AgencyItem from '../components/AgencyItem'
import AgencyForm from '../components/AgencyForm' import AgencyForm from '../components/AgencyForm'
@ -42,10 +43,9 @@ class Main extends Component {
<Route path={`${match.url}agency/:agencyId/:agencyChild`} component={AgencyItem} /> <Route path={`${match.url}agency/:agencyId/:agencyChild`} component={AgencyItem} />
<Route exact path={`${match.url}agency`} component={AgencyList} /> <Route exact path={`${match.url}agency`} component={AgencyList} />
<Route exact path={`${match.url}calendar/new`} component={AgencyForm} /> <Route exact path={`${match.url}calendar/new`} component={CalendarForm} />
<Route exact path={`${match.url}calendar/:serviceId`} component={AgencyForm} /> <Route exact path={`${match.url}calendar/:serviceId`} component={CalendarForm} />
<Route path={`${match.url}calendar/:serviceId/edit`} component={AgencyForm} /> <Route exact path={`${match.url}calendar`} component={CalendarList} />
<Route exact path={`${match.url}calendar`} component={AgencyList} />
</Switch> </Switch>
</div> </div>
</div> </div>

4
src/container/Public.js

@ -31,7 +31,7 @@ class Public extends Component {
} }
render() { render() {
const { loggedIn } = this.props const { loggedIn, failMessage } = this.props
return ( return (
<div style={{minHeight: '100vh'}} <div style={{minHeight: '100vh'}}
className="columns is-mobile is-centered is-desktop is-vcentered"> className="columns is-mobile is-centered is-desktop is-vcentered">
@ -45,6 +45,7 @@ class Public extends Component {
{loggedIn === true {loggedIn === true
? <Redirect to={'/'} /> ? <Redirect to={'/'} />
: <Login : <Login
failMessage={failMessage}
fetchAuth={this.handleFetchAuth} fetchAuth={this.handleFetchAuth}
updateField={this.updateField} /> } updateField={this.updateField} /> }
{/* <hr /> */} {/* <hr /> */}
@ -66,6 +67,7 @@ class Public extends Component {
} }
const mapStateToProps = state => ({ const mapStateToProps = state => ({
failMessage: state.auth.msg,
token: getToken(state.auth), token: getToken(state.auth),
loggedIn: loggedIn(state.auth), loggedIn: loggedIn(state.auth),
}) })

7
src/reducers/auth.js

@ -6,6 +6,7 @@ import {
const tokenInitialState = { const tokenInitialState = {
token: null, token: null,
fetching: false, fetching: false,
msg: '',
} }
const auth = (state = tokenInitialState, action) => { const auth = (state = tokenInitialState, action) => {
switch(action.type) { switch(action.type) {
@ -13,21 +14,27 @@ const auth = (state = tokenInitialState, action) => {
return { return {
token: null, token: null,
fetching: true, fetching: true,
msg: ''
} }
case SUCCESS_LOGIN: case SUCCESS_LOGIN:
return { return {
token: action.body.token, token: action.body.token,
fetching: false, fetching: false,
msg: '',
} }
case FAILED_LOGIN: case FAILED_LOGIN:
const { data } = action.body.response
const msg = Object.keys(data).map(ele => data[ele]).join(',')
return { return {
token: null, token: null,
fetching: false, fetching: false,
msg
} }
case SUCCESS_LOGOUT: case SUCCESS_LOGOUT:
return { return {
token: null, token: null,
fetching: false, fetching: false,
msg: '',
}; };
default: default:
return state; return state;

2
src/reducers/calendar.js

@ -14,11 +14,9 @@ const calendarInitState = {
const calendar = (state = calendarInitState, action) => { const calendar = (state = calendarInitState, action) => {
switch(action.type) { switch(action.type) {
case CALENDAR_REQUEST: case CALENDAR_REQUEST:
const { query } = action.meta
return { return {
...state, ...state,
fetching: true, fetching: true,
query,
} }
case CALENDAR_SUCCESS: case CALENDAR_SUCCESS:
const { count, next, prev, results } = action.payload const { count, next, prev, results } = action.payload

22
src/reducers/fareattr.js

@ -1,26 +1,26 @@
import { import {
CALENDAR_CREATE, CALENDAR_DELETE, CALENDAR_UPDATE, FAREATTR_CREATE, FAREATTR_DELETE, FAREATTR_UPDATE,
CALENDAR_REQUEST, CALENDAR_SUCCESS, CALENDAR_FAILURE, FAREATTR_REQUEST, FAREATTR_SUCCESS, FAREATTR_FAILURE,
} from '../constants/ActionTypes' } from '../constants/ActionTypes'
const calendarInitState = { const fareAttrInitState = {
results: [], results: [],
next: null, next: null,
count: 0, count: 0,
fetching: false, fetching: false,
query: '', query: '',
} }
const calendar = (state = calendarInitState, action) => { const fareAttr = (state = fareAttrInitState, action) => {
switch(action.type) { switch(action.type) {
case CALENDAR_REQUEST: case FAREATTR_REQUEST:
const { query } = action.meta const { query } = action.meta
return { return {
...state, ...state,
fetching: true, fetching: true,
query, query,
} }
case CALENDAR_SUCCESS: case FAREATTR_SUCCESS:
const { count, next, prev, results } = action.payload const { count, next, prev, results } = action.payload
return { return {
...state, ...state,
@ -32,7 +32,7 @@ const calendar = (state = calendarInitState, action) => {
...results, ...results,
] ]
} }
case CALENDAR_UPDATE: case FAREATTR_UPDATE:
const { id } = action.payload const { id } = action.payload
const oldResults = state.results const oldResults = state.results
const targetInd = oldResults.findIndex(ele => ele.id === id) const targetInd = oldResults.findIndex(ele => ele.id === id)
@ -45,7 +45,7 @@ const calendar = (state = calendarInitState, action) => {
...oldResults.slice(targetInd + 1) ...oldResults.slice(targetInd + 1)
] ]
} }
case CALENDAR_CREATE: case FAREATTR_CREATE:
return { return {
...state, ...state,
fetching: false, fetching: false,
@ -55,7 +55,7 @@ const calendar = (state = calendarInitState, action) => {
action.payload, action.payload,
] ]
} }
case CALENDAR_DELETE: case FAREATTR_DELETE:
const deleteInd = state.results.findIndex(ele => ele.id === action.meta.id) const deleteInd = state.results.findIndex(ele => ele.id === action.meta.id)
return { return {
...state, ...state,
@ -66,7 +66,7 @@ const calendar = (state = calendarInitState, action) => {
...state.results.slice(deleteInd + 1) ...state.results.slice(deleteInd + 1)
] ]
} }
case CALENDAR_FAILURE: case FAREATTR_FAILURE:
return { return {
...state, ...state,
fetching: false, fetching: false,
@ -76,4 +76,4 @@ const calendar = (state = calendarInitState, action) => {
} }
} }
export default calendar export default fareAttr

2
src/reducers/index.js

@ -4,6 +4,7 @@ import auth from './auth'
import agency from './agency' import agency from './agency'
import route from './route' import route from './route'
import fareattr from './fareattr' import fareattr from './fareattr'
import calendar from './calendar'
export default combineReducers({ export default combineReducers({
auth, auth,
@ -11,4 +12,5 @@ export default combineReducers({
agency, agency,
route, route,
fareattr, fareattr,
calendar,
}) })

2
src/store.js

@ -10,7 +10,7 @@ import gruntApp from './reducers'
const persistConfig = { const persistConfig = {
key: 'root', key: 'root',
storage, storage,
blacklist: ['agency', 'route'] blacklist: ['agency', 'route', 'calendar']
} }
const middleware = [ thunk, apiMiddleware ] const middleware = [ thunk, apiMiddleware ]

Loading…
Cancel
Save