diff --git a/bikeshop_project/assets/js/bikes/components/BikeForm/index.jsx b/bikeshop_project/assets/js/bikes/components/BikeForm/index.jsx index 83f9b43..8dbf90e 100644 --- a/bikeshop_project/assets/js/bikes/components/BikeForm/index.jsx +++ b/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 (
+
+
+ + {stateMenuItems([currentState].concat(availableStates))} + +
+
} @@ -126,7 +141,6 @@ class BikeForm extends React.Component {
} - {!create &&
@@ -134,7 +148,7 @@ class BikeForm extends React.Component { name="cpic_searched_at" component={renderTextField} floatingLabelText="CPIC searched" - disabled + readOnly />
@@ -149,7 +163,7 @@ class BikeForm extends React.Component { />
- this.props.checkCpic(this.props.id)} disabled={!!this.props.cpic_searched} primary /> + this.props.checkCpic(id)} disabled={cpicSearched} primary />
} @@ -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)), }), diff --git a/bikeshop_project/assets/js/bikes/components/BikeForm/utils.jsx b/bikeshop_project/assets/js/bikes/components/BikeForm/utils.jsx index 04b48ce..caa384f 100644 --- a/bikeshop_project/assets/js/bikes/components/BikeForm/utils.jsx +++ b/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 => ); + export const sourceMenuItems = sources.map(s => - , + , ); export const renderTextField = ({ input, meta: { touched, error }, ...custom }) => ( diff --git a/bikeshop_project/assets/js/bikes/components/BikeModal/index.jsx b/bikeshop_project/assets/js/bikes/components/BikeModal/index.jsx index a2fd822..2d6c994 100644 --- a/bikeshop_project/assets/js/bikes/components/BikeModal/index.jsx +++ b/bikeshop_project/assets/js/bikes/components/BikeModal/index.jsx @@ -22,7 +22,6 @@ class BikeModal extends React.Component { > ) diff --git a/bikeshop_project/assets/js/components/SignedInList.jsx b/bikeshop_project/assets/js/components/SignedInList.jsx index f63a078..e814e31 100644 --- a/bikeshop_project/assets/js/components/SignedInList.jsx +++ b/bikeshop_project/assets/js/components/SignedInList.jsx @@ -104,7 +104,6 @@ class SignedInList extends React.Component { } - ); }