Browse Source

Display available states.

feature/bike-tracking
Drew Larson 8 years ago
parent
commit
4af8c055e3
  1. 48
      bikeshop_project/assets/js/bikes/components/BikeForm/index.jsx
  2. 58
      bikeshop_project/assets/js/bikes/components/BikeForm/utils.jsx
  3. 1
      bikeshop_project/assets/js/bikes/components/BikeModal/index.jsx
  4. 1
      bikeshop_project/assets/js/components/SignedInList.jsx

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

@ -4,7 +4,7 @@ import { connect } from 'react-redux';
import FlatButton from 'material-ui/FlatButton'; import FlatButton from 'material-ui/FlatButton';
import RaisedButton from 'material-ui/RaisedButton'; import RaisedButton from 'material-ui/RaisedButton';
import Size from '../Size'; import Size from '../Size';
import { renderCheckbox, renderSelectField, renderTextField, sourceMenuItems } from './utils'; import { renderCheckbox, renderSelectField, renderTextField, sourceMenuItems, stateMenuItems, getRequiredFields } from './utils';
import { updateBike, saveBike, checkCpic } from '../../actions'; import { updateBike, saveBike, checkCpic } from '../../actions';
const styles = { const styles = {
@ -19,15 +19,20 @@ const styles = {
}, },
}; };
const validate = (values) => { const validate = (values, props) => {
const errors = {}; const errors = {};
const requiredFields = ['make', 'colour', 'size', 'serial_number', 'donation_source']; console.log(values);
const requiredFields = getRequiredFields(values.new_state);
requiredFields.forEach((field) => { requiredFields.forEach((field) => {
if (!values[field]) { if (!values[field]) {
errors[field] = 'Required'; errors[field] = 'Required';
} }
}); });
if (!props.availableStates.includes(values.new_state)) {
errors['new_state'] = `${values.new_state} is not allowed.`;
}
return errors; return errors;
}; };
@ -43,11 +48,22 @@ const handleSubmit = (data, dispatch, props) => {
class BikeForm extends React.Component { class BikeForm extends React.Component {
render() { render() {
const { create } = this.props; const { create, cpicSearched, id, availableStates, currentState } = this.props;
return ( return (
<div> <div>
<form onSubmit={this.props.handleSubmit}> <form onSubmit={this.props.handleSubmit}>
<div className="mdl-grid">
<div className="mdl-cell mdl-cell--3-col">
<Field
name="new_state"
component={renderSelectField}
floatingLabelText="State"
fullWidth
>
{stateMenuItems([currentState].concat(availableStates))}
</Field>
</div>
</div>
<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
@ -98,7 +114,6 @@ class BikeForm extends React.Component {
floatingLabelText="Created at" floatingLabelText="Created at"
fullWidth fullWidth
readOnly readOnly
disabled
/> />
</div> </div>
} }
@ -126,7 +141,6 @@ class BikeForm extends React.Component {
</div> </div>
</div> </div>
} }
{!create && {!create &&
<div className="content-grid mdl-grid" style={styles.bottom}> <div className="content-grid mdl-grid" style={styles.bottom}>
<div className="mdl-cell mdl-cell--6-col"> <div className="mdl-cell mdl-cell--6-col">
@ -134,7 +148,7 @@ class BikeForm extends React.Component {
name="cpic_searched_at" name="cpic_searched_at"
component={renderTextField} component={renderTextField}
floatingLabelText="CPIC searched" floatingLabelText="CPIC searched"
disabled readOnly
/> />
</div> </div>
<div className="mdl-cell mdl-cell--4-col"> <div className="mdl-cell mdl-cell--4-col">
@ -149,7 +163,7 @@ class BikeForm extends React.Component {
/> />
</div> </div>
<div className="mdl-cell mdl-cell--2-col"> <div className="mdl-cell mdl-cell--2-col">
<FlatButton label="Check" onTouchTap={() => this.props.checkCpic(this.props.id)} disabled={!!this.props.cpic_searched} primary /> <FlatButton label="Check" onTouchTap={() => this.props.checkCpic(id)} disabled={cpicSearched} primary />
</div> </div>
</div> </div>
} }
@ -196,15 +210,17 @@ BikeForm = reduxForm({
onSubmit: handleSubmit, onSubmit: handleSubmit,
})(BikeForm); })(BikeForm);
const selector = formValueSelector('BikeForm')
BikeForm = connect( BikeForm = connect(
state => ({ state => {
initialValues: state.bikes.form.bike, // pull initial values from account reducer return {
initialValues: {...state.bikes.form.bike, new_state: state.bikes.form.bike.state.toLowerCase()}, // pull initial values from account reducer
create: state.bikes.form.create, create: state.bikes.form.create,
cpic_searched: selector(state, 'cpic_searched_at'), cpicSearched: !!state.bikes.form.bike.cpic_searched_at,
id: selector(state, 'id'), id: state.bikes.form.bike.id,
}), availableStates: state.bikes.form.bike.available_states,
currentState: state.bikes.form.bike.state.toLowerCase(),
};
},
dispatch => ({ dispatch => ({
checkCpic: id => dispatch(checkCpic(id)), checkCpic: id => dispatch(checkCpic(id)),
}), }),

58
bikeshop_project/assets/js/bikes/components/BikeForm/utils.jsx

@ -1,3 +1,4 @@
import moment from 'moment';
import React from 'react'; import React from 'react';
import Checkbox from 'material-ui/Checkbox'; import Checkbox from 'material-ui/Checkbox';
import MenuItem from 'material-ui/MenuItem'; import MenuItem from 'material-ui/MenuItem';
@ -6,7 +7,7 @@ import TextField from 'material-ui/TextField';
const sources = ['COS_BIKE_DIVERSION_PILOT', 'UOFS', 'DROP_OFF']; const sources = ['COS_BIKE_DIVERSION_PILOT', 'UOFS', 'DROP_OFF'];
const friendly = (s) => { const friendlySources = (s) => {
switch (s) { switch (s) {
case 'COS_BIKE_DIVERSION_PILOT': case 'COS_BIKE_DIVERSION_PILOT':
return 'City of Saskatoon Bike Diversion Pilot'; return 'City of Saskatoon Bike Diversion Pilot';
@ -19,8 +20,61 @@ const friendly = (s) => {
} }
}; };
const states = ['received', 'assessed', 'available', 'claimed', 'purchased', 'scrapped', 'transferred_to_police'];
const friendlStates = (s) => {
switch (s) {
case 'received':
return 'Received';
case 'assessed':
return 'Assessed';
case 'available':
return 'Available';
case 'claimed':
return 'Claimed';
case 'purchased':
return 'Purchased';
case 'scrapped':
return 'Scrapped';
case 'transferred_to_police':
return 'Transferred to police';
default:
throw Error(`${s} is not an allowed state.`)
}
};
export const getRequiredFields = (bikeState) => {
switch (bikeState) {
case 'received':
return ['make', 'colour', 'size', 'serial_number', 'donation_source'];
case 'assessed':
return ['make', 'colour', 'size', 'serial_number', 'donation_source', 'price'];
case 'available':
return ['make', 'colour', 'size', 'serial_number', 'donation_source', 'price', 'stolen', 'cpic_searched'];
case 'claimed':
return ['make', 'colour', 'size', 'serial_number', 'donation_source', 'price', 'stolen', 'cpic_searched'];
case 'purchased':
return ['make', 'colour', 'size', 'serial_number', 'donation_source', 'price', 'stolen', 'cpic_searched'];
case 'scrapped':
return ['make', 'colour', 'size', 'serial_number', 'donation_source', 'cpic_searched'];
case 'transferred_to_police':
return ['make', 'colour', 'size', 'serial_number', 'donation_source', 'cpic_searched'];
default:
throw new Error(`${bikeState} is an invalid state.`);
}
}
const canAvailable = (stolen, cpicSearched) => !stolen && cpicSearched;
const canClaim = (claimedBy, lastWorkedOn) => !claimedBy || lastWorkedOn.isAfter(moment().add(4, 'weeks'));
const canPurchase = canClaim;
const canScrap = (stripped, claim) => stripped && claim;
const canTransferToPolice = stolen => stolen;
export const stateMenuItems = availableStates => states
.filter(s => availableStates.includes(s))
.map(s => <MenuItem key={s} value={s} primaryText={friendlStates(s)} />);
export const sourceMenuItems = sources.map(s => export const sourceMenuItems = sources.map(s =>
<MenuItem key={s} value={s} primaryText={friendly(s)} />, <MenuItem key={s} value={s} primaryText={friendlySources(s)} />,
); );
export const renderTextField = ({ input, meta: { touched, error }, ...custom }) => ( export const renderTextField = ({ input, meta: { touched, error }, ...custom }) => (

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

@ -22,7 +22,6 @@ class BikeModal extends React.Component {
> >
<BikeForm <BikeForm
handleModalClose={this.props.handleClose} handleModalClose={this.props.handleClose}
enableReinitialize
/> />
</Dialog> </Dialog>
) )

1
bikeshop_project/assets/js/components/SignedInList.jsx

@ -104,7 +104,6 @@ class SignedInList extends React.Component {
} }
</TableBody> </TableBody>
</Table> </Table>
</div> </div>
); );
} }

Loading…
Cancel
Save