Browse Source

Create new bikes!

feature/bike-tracking
Drew Larson 8 years ago
parent
commit
e061320ee7
  1. 5
      bikeshop_project/assets/js/bikes/actions.js
  2. 13
      bikeshop_project/assets/js/bikes/components/BikeForm/index.jsx
  3. 25
      bikeshop_project/assets/js/bikes/components/BikeTable/index.jsx
  4. 26
      bikeshop_project/assets/js/bikes/sagas.js
  5. 19
      bikeshop_project/assets/js/bikes/services/index.js

5
bikeshop_project/assets/js/bikes/actions.js

@ -10,5 +10,6 @@ export const setBikeIsSaving = createAction('set bike.isSaving');
export const setBikeSaveFailed = createAction('set bike.isSaving'); export const setBikeSaveFailed = createAction('set bike.isSaving');
export const editBike = createAction('edit bike'); export const editBike = createAction('edit bike');
export const createBike = createAction('create bike'); export const createBike = createAction('create bike');
export const saveBike = createAction('save bike'); export const updateBike = createAction('update bike');
export const mergeBike = createAction('merge bike'); export const mergeBike = createAction('merge bike');
export const saveBike = createAction('save bike');

13
bikeshop_project/assets/js/bikes/components/BikeForm/index.jsx

@ -12,7 +12,7 @@ import fetch from 'isomorphic-fetch';
import moment from 'moment-timezone'; import moment from 'moment-timezone';
import Source from '../Source'; import Source from '../Source';
import Size from '../Size'; import Size from '../Size';
import { saveBike } from '../../actions'; import { updateBike, saveBike } from '../../actions';
const styles = { const styles = {
block: { block: {
@ -85,9 +85,14 @@ const validate = (values) => {
return errors; return errors;
}; };
const handleSubmit = (data, dispatch) => { const handleSubmit = (data, dispatch, props) => {
console.log(data); const { create } = props;
dispatch(saveBike(data)); if (create) {
dispatch(saveBike(data));
} else {
dispatch(updateBike(data));
}
}; };
class BikeForm extends React.Component { class BikeForm extends React.Component {

25
bikeshop_project/assets/js/bikes/components/BikeTable/index.jsx

@ -6,7 +6,7 @@ import ContentAdd from 'material-ui/svg-icons/content/add';
import React from 'react'; import React from 'react';
import { friendlySize } from '../Size'; import { friendlySize } from '../Size';
import BikeModal from '../BikeModal'; import BikeModal from '../BikeModal';
import { fetchBikes, setBike, editBike } from '../../actions'; import { fetchBikes, setBike, editBike, createBike } from '../../actions';
class BikeTableComponent extends React.Component { class BikeTableComponent extends React.Component {
constructor(props) { constructor(props) {
@ -18,7 +18,8 @@ class BikeTableComponent extends React.Component {
}, },
}; };
this.handleOpen = this.handleOpen.bind(this); this.handleOpenEdit = this.handleOpenEdit.bind(this);
this.handleOpenCreate = this.handleOpenCreate.bind(this);
this.handleClose = this.handleClose.bind(this); this.handleClose = this.handleClose.bind(this);
this.renderBikes = this.renderBikes.bind(this); this.renderBikes = this.renderBikes.bind(this);
} }
@ -27,7 +28,7 @@ class BikeTableComponent extends React.Component {
this.props.fetchBikes(); this.props.fetchBikes();
} }
handleOpen(bike) { handleOpenEdit(bike) {
this.setState({ this.setState({
...this.state, ...this.state,
bikeModal: { bikeModal: {
@ -38,6 +39,17 @@ class BikeTableComponent extends React.Component {
this.props.editBike(bike); this.props.editBike(bike);
} }
handleOpenCreate() {
this.setState({
...this.state,
bikeModal: {
...this.state.bikeModal,
open: true,
},
});
this.props.createBike();
}
handleClose() { handleClose() {
this.setState({ this.setState({
...this.state, ...this.state,
@ -57,7 +69,7 @@ class BikeTableComponent extends React.Component {
<TableRowColumn>{bike.serial_number}</TableRowColumn> <TableRowColumn>{bike.serial_number}</TableRowColumn>
<TableRowColumn>{bike.state}</TableRowColumn> <TableRowColumn>{bike.state}</TableRowColumn>
<TableRowColumn>{bike.claimed_by}</TableRowColumn> <TableRowColumn>{bike.claimed_by}</TableRowColumn>
<TableRowColumn><FlatButton label="Edit" primary onTouchTap={(e) => this.handleOpen(bike)} /></TableRowColumn> <TableRowColumn><FlatButton label="Edit" primary onTouchTap={(e) => this.handleOpenEdit(bike)} /></TableRowColumn>
</TableRow> </TableRow>
)); ));
@ -71,7 +83,7 @@ class BikeTableComponent extends React.Component {
<div className="mdl-grid"> <div className="mdl-grid">
<div className="mdl-cell mdl-cell--12-col"> <div className="mdl-cell mdl-cell--12-col">
<h3>Bikes</h3> <h3>Bikes</h3>
<FloatingActionButton onTouchTap={this.handleAddBike}> <FloatingActionButton onTouchTap={this.handleOpenCreate}>
<ContentAdd /> <ContentAdd />
</FloatingActionButton> </FloatingActionButton>
<Table selectable={false}> <Table selectable={false}>
@ -118,6 +130,9 @@ const mapDispatchToProps = dispatch => ({
}, },
editBike: (bike) => { editBike: (bike) => {
dispatch(editBike(bike)); dispatch(editBike(bike));
},
createBike: () => {
dispatch(createBike())
} }
}); });

26
bikeshop_project/assets/js/bikes/sagas.js

@ -1,7 +1,8 @@
import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'; import { call, put, takeEvery } from 'redux-saga/effects';
import { fetchBikes as fetchBikesAction, setBikes, setBikesIsFetching, setBikesFetched, import { fetchBikes as fetchBikesAction, setBikes, setBikesIsFetching, setBikesFetched,
setBikesFetchFailed, setBikeSaved, setBikeSaveFailed, setBikeIsSaving, saveBike as saveBikeAction, mergeBike } from './actions'; setBikesFetchFailed, setBikeSaved, setBikeSaveFailed, setBikeIsSaving, updateBike as updateBikeAction,
import { normalize, denormalize } from 'normalizr'; mergeBike, saveBike as saveBikeAction } from './actions';
import { normalize } from 'normalizr';
import * as schema from './schema'; import * as schema from './schema';
import Api from './services'; import Api from './services';
@ -25,6 +26,24 @@ function* watchFetchBikes() {
yield takeEvery(fetchBikesAction.toString(), fetchBikes); yield takeEvery(fetchBikesAction.toString(), fetchBikes);
} }
function* updateBike(action) {
try {
yield put({ type: setBikeIsSaving.toString(), payload: true });
const bike = yield call(Api.updateBike, action.payload);
yield put({ type: mergeBike.toString(), payload: normalize([bike], schema.bikes)})
yield put({ type: setBikeSaved.toString(), payload: true})
} catch (e) {
yield put({ type: setBikeSaveFailed, payload: false });
throw(e);
} finally {
yield put({ type: setBikeIsSaving.toString(), payload: false });
}
}
function* watchUpdateBike() {
yield takeEvery(updateBikeAction.toString(), updateBike)
}
function* saveBike(action) { function* saveBike(action) {
try { try {
yield put({ type: setBikeIsSaving.toString(), payload: true }); yield put({ type: setBikeIsSaving.toString(), payload: true });
@ -46,6 +65,7 @@ function* watchSaveBike() {
export default function* rootSaga() { export default function* rootSaga() {
yield [ yield [
watchFetchBikes(), watchFetchBikes(),
watchUpdateBike(),
watchSaveBike(), watchSaveBike(),
]; ];
}; };

19
bikeshop_project/assets/js/bikes/services/index.js

@ -28,8 +28,8 @@ const Api = {
throw error; throw error;
}); });
}, },
saveBike(data) { updateBike(data) {
return fetch(`/api/v1/bikes/${data.id}/`, { return fetch(data.url, {
credentials: 'same-origin', credentials: 'same-origin',
method: 'PUT', method: 'PUT',
headers, headers,
@ -43,6 +43,21 @@ const Api = {
throw error; throw error;
}); });
}, },
saveBike(data) {
return fetch(`/api/v1/bikes/`, {
credentials: 'same-origin',
method: 'POST',
headers,
body: JSON.stringify(data),
})
.then(checkStatus)
.then(parseJson)
.then(data => data)
.catch((error) => {
console.log('request failed', error);
throw error;
});
},
}; };
export default Api; export default Api;

Loading…
Cancel
Save