Browse Source

Edit bikes.

feature/bike-tracking
Drew Larson 8 years ago
parent
commit
1dbefb2d4b
  1. 1
      bikeshop_project/assets/js/bikes/actions.js
  2. 40
      bikeshop_project/assets/js/bikes/components/BikeForm/index.jsx
  3. 3
      bikeshop_project/assets/js/bikes/components/BikeModal/index.jsx
  4. 13
      bikeshop_project/assets/js/bikes/components/BikeTable/index.jsx
  5. 4
      bikeshop_project/assets/js/bikes/index.jsx
  6. 36
      bikeshop_project/assets/js/bikes/sagas.js
  7. 10
      bikeshop_project/assets/js/bikes/services/index.js

1
bikeshop_project/assets/js/bikes/actions.js

@ -10,3 +10,4 @@ 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');

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

@ -12,6 +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';
const styles = { const styles = {
block: { block: {
@ -84,7 +85,10 @@ const validate = (values) => {
return errors; return errors;
}; };
const handleSubmit = data => false; const handleSubmit = (data, dispatch) => {
console.log(data);
dispatch(saveBike(data));
};
class BikeForm extends React.Component { class BikeForm extends React.Component {
constructor({ bike, create }) { constructor({ bike, create }) {
@ -100,18 +104,6 @@ class BikeForm extends React.Component {
} }
} }
handleChange(event, value) {
this.setState({ bike: { ...this.state.bike, [event.target.name]: value } });
}
handleSizeChange(event, index, value) {
this.setState({ bike: { ...this.state.bike, size: value } });
}
handleSourceChange(event, index, value) {
this.setState({ bike: { ...this.state.bike, source: value } });
}
handleCpicCheck() { handleCpicCheck() {
const id = this.state.bike.id; const id = this.state.bike.id;
const serialNumber = this.state.bike.serial_number; const serialNumber = this.state.bike.serial_number;
@ -160,24 +152,11 @@ class BikeForm extends React.Component {
} }
render() { render() {
// const timezone = moment.tz.guess(); const { create } = this.props;
// const {
// claimed_at,
// claimed_by,
// cpic_searched_at,
// created_at,
// stolen,
// checked,
// } = this.props.bike || {};
const create = this.props.create;
// const createdAtFormatted = (moment(created_at).isValid()) ? moment(created_at).tz(timezone).fromNow() : '';
// const claimedAtFormatted = (moment(claimed_at).isValid()) ? moment(claimed_at).tz(timezone).fromNow() : '';
// const cpicSearchedAtFormatted = (moment(cpic_searched_at).isValid()) ? moment(cpic_searched_at).tz(timezone)
// .fromNow() : '';
return ( return (
<div> <div>
<form onSubmit={handleSubmit}> <form onSubmit={this.props.handleSubmit}>
<div className="mdl-grid"> <div className="mdl-grid">
<div className="mdl-cell mdl-cell--3-col"> <div className="mdl-cell mdl-cell--3-col">
<Field <Field
@ -286,7 +265,7 @@ class BikeForm extends React.Component {
<div className="mdl-grid" style={styles.bottom}> <div className="mdl-grid" style={styles.bottom}>
<div className="mdl-cell mdl-cell--8-col"> <div className="mdl-cell mdl-cell--8-col">
<Field <Field
name="donation_source" name="source"
component={renderSelectField} component={renderSelectField}
floatingLabelText="Donation source" floatingLabelText="Donation source"
fullWidth fullWidth
@ -310,7 +289,7 @@ class BikeForm extends React.Component {
</div> </div>
<div className="mdl-grid"> <div className="mdl-grid">
<div style={{ textAlign: 'right' }} className="mdl-cell mdl-cell--12-col"> <div style={{ textAlign: 'right' }} className="mdl-cell mdl-cell--12-col">
<RaisedButton style={{ marginRight: '8px' }} label="Cancel" onTouchTap={this.props.handleClose} secondary /> <RaisedButton style={{ marginRight: '8px' }} label="Cancel" onTouchTap={this.props.handleModalClose} secondary />
<RaisedButton type="submit" label="Save" default disabled={this.props.pristine || this.props.submitting || this.props.invalid} /> <RaisedButton type="submit" label="Save" default disabled={this.props.pristine || this.props.submitting || this.props.invalid} />
</div> </div>
</div> </div>
@ -323,6 +302,7 @@ class BikeForm extends React.Component {
BikeForm = reduxForm({ BikeForm = reduxForm({
form: 'BikeForm', // a unique identifier for this form form: 'BikeForm', // a unique identifier for this form
validate, validate,
onSubmit: handleSubmit,
})(BikeForm); })(BikeForm);
const selector = formValueSelector('BikeForm') const selector = formValueSelector('BikeForm')

3
bikeshop_project/assets/js/bikes/components/BikeModal/index.jsx

@ -6,6 +6,7 @@ import BikeForm from '../BikeForm';
/** /**
* A modal dialog can only be closed by selecting one of the actions. * A modal dialog can only be closed by selecting one of the actions.
*/ */
class BikeModal extends React.Component { class BikeModal extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
@ -16,9 +17,11 @@ class BikeModal extends React.Component {
<Dialog <Dialog
title='Bike' title='Bike'
open={this.props.open} open={this.props.open}
modal={false}
autoScrollBodyContent autoScrollBodyContent
> >
<BikeForm <BikeForm
handleModalClose={this.props.handleClose}
enableReinitialize enableReinitialize
/> />
} }

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

@ -15,11 +15,11 @@ class BikeTableComponent extends React.Component {
this.state = { this.state = {
bikeModal: { bikeModal: {
open: false, open: false,
bike: undefined,
}, },
}; };
this.handleOpen = this.handleOpen.bind(this); this.handleOpen = this.handleOpen.bind(this);
this.handleClose = this.handleClose.bind(this);
this.renderBikes = this.renderBikes.bind(this); this.renderBikes = this.renderBikes.bind(this);
} }
@ -38,6 +38,16 @@ class BikeTableComponent extends React.Component {
this.props.editBike(bike); this.props.editBike(bike);
} }
handleClose() {
this.setState({
...this.state,
bikeModal: {
...this.state.bikeModal,
open: false,
},
});
}
renderBikes(bikes) { renderBikes(bikes) {
const bikeRows = bikes.map(bike => ( const bikeRows = bikes.map(bike => (
<TableRow selectable={false} key={bike.id}> <TableRow selectable={false} key={bike.id}>
@ -88,6 +98,7 @@ class BikeTableComponent extends React.Component {
</div> </div>
<BikeModal <BikeModal
open={this.state.bikeModal.open} open={this.state.bikeModal.open}
handleClose={this.handleClose}
/> />
</div> </div>
); );

4
bikeshop_project/assets/js/bikes/index.jsx

@ -9,7 +9,7 @@ import bikesReducer from './reducers';
import createSagaMiddleware from 'redux-saga' import createSagaMiddleware from 'redux-saga'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import BikeTable from './components/BikeTable'; import BikeTable from './components/BikeTable';
import watchFetchBikes from './sagas'; import rootSaga from './sagas';
// Needed for onTouchTap // Needed for onTouchTap
@ -30,7 +30,7 @@ const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(combinedReducers, composeEnhancers(applyMiddleware(sagaMiddleware))); const store = createStore(combinedReducers, composeEnhancers(applyMiddleware(sagaMiddleware)));
sagaMiddleware.run(watchFetchBikes); sagaMiddleware.run(rootSaga);
class App extends React.Component { class App extends React.Component {

36
bikeshop_project/assets/js/bikes/sagas.js

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

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

@ -1,4 +1,8 @@
import fetch from 'isomorphic-fetch'; import fetch from 'isomorphic-fetch';
import Cookies from 'js-cookie';
const csrfToken = Cookies.get('csrftoken')
const headers = new Headers({ 'X-CSRFToken': csrfToken, 'Content-Type': 'application/json' });
const checkStatus = (response) => { const checkStatus = (response) => {
if (response.status >= 200 && response.status < 300) { if (response.status >= 200 && response.status < 300) {
@ -24,10 +28,12 @@ const Api = {
throw error; throw error;
}); });
}, },
saveBike(id) { saveBike(data) {
return fetch(`/api/v1/bike/${id}`, { return fetch(`/api/v1/bikes/${data.id}/`, {
credentials: 'same-origin', credentials: 'same-origin',
method: 'PUT', method: 'PUT',
headers,
body: JSON.stringify(data),
}) })
.then(checkStatus) .then(checkStatus)
.then(parseJson) .then(parseJson)

Loading…
Cancel
Save