Browse Source

Display available states.

feature/bike-tracking
Drew Larson 7 years ago
parent
commit
4af8c055e3
  1. 50
      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

50
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 RaisedButton from 'material-ui/RaisedButton';
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';
const styles = {
@ -19,15 +19,20 @@ const styles = {
},
};
const validate = (values) => {
const validate = (values, props) => {
const errors = {};
const requiredFields = ['make', 'colour', 'size', 'serial_number', 'donation_source'];
console.log(values);
const requiredFields = getRequiredFields(values.new_state);
requiredFields.forEach((field) => {
if (!values[field]) {
errors[field] = 'Required';
}
});
if (!props.availableStates.includes(values.new_state)) {
errors['new_state'] = `${values.new_state} is not allowed.`;
}
return errors;
};
@ -43,11 +48,22 @@ const handleSubmit = (data, dispatch, props) => {
class BikeForm extends React.Component {
render() {
const { create } = this.props;
const { create, cpicSearched, id, availableStates, currentState } = this.props;
return (
<div>
<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-cell mdl-cell--3-col">
<Field
@ -98,7 +114,6 @@ class BikeForm extends React.Component {
floatingLabelText="Created at"
fullWidth
readOnly
disabled
/>
</div>
}
@ -126,7 +141,6 @@ class BikeForm extends React.Component {
</div>
</div>
}
{!create &&
<div className="content-grid mdl-grid" style={styles.bottom}>
<div className="mdl-cell mdl-cell--6-col">
@ -134,7 +148,7 @@ class BikeForm extends React.Component {
name="cpic_searched_at"
component={renderTextField}
floatingLabelText="CPIC searched"
disabled
readOnly
/>
</div>
<div className="mdl-cell mdl-cell--4-col">
@ -149,7 +163,7 @@ class BikeForm extends React.Component {
/>
</div>
<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>
}
@ -196,15 +210,17 @@ BikeForm = reduxForm({
onSubmit: handleSubmit,
})(BikeForm);
const selector = formValueSelector('BikeForm')
BikeForm = connect(
state => ({
initialValues: state.bikes.form.bike, // pull initial values from account reducer
create: state.bikes.form.create,
cpic_searched: selector(state, 'cpic_searched_at'),
id: selector(state, 'id'),
}),
state => {
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,
cpicSearched: !!state.bikes.form.bike.cpic_searched_at,
id: state.bikes.form.bike.id,
availableStates: state.bikes.form.bike.available_states,
currentState: state.bikes.form.bike.state.toLowerCase(),
};
},
dispatch => ({
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 Checkbox from 'material-ui/Checkbox';
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 friendly = (s) => {
const friendlySources = (s) => {
switch (s) {
case 'COS_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 =>
<MenuItem key={s} value={s} primaryText={friendly(s)} />,
<MenuItem key={s} value={s} primaryText={friendlySources(s)} />,
);
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
handleModalClose={this.props.handleClose}
enableReinitialize
/>
</Dialog>
)

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

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

Loading…
Cancel
Save