mirror of
				https://github.com/fspc/workstand.git
				synced 2025-10-29 15:45:36 -04:00 
			
		
		
		
	Refactor form.
This commit is contained in:
		
							parent
							
								
									5d2514917f
								
							
						
					
					
						commit
						6aa7614a8b
					
				
							
								
								
									
										190
									
								
								bikeshop_project/assets/js/bikes/components/BikeForm/index.jsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										190
									
								
								bikeshop_project/assets/js/bikes/components/BikeForm/index.jsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,190 @@ | ||||
| import Checkbox from 'material-ui/Checkbox'; | ||||
| import FlatButton from 'material-ui/FlatButton'; | ||||
| import moment from 'moment-timezone'; | ||||
| import React from 'react'; | ||||
| import TextField from 'material-ui/TextField'; | ||||
| import Source from '../Source'; | ||||
| import Size from '../Size'; | ||||
| 
 | ||||
| const styles = { | ||||
|   block: { | ||||
|     maxWidth: 250, | ||||
|   }, | ||||
|   checkbox: { | ||||
|     marginBottom: 16, | ||||
|   }, | ||||
|   bottom: { | ||||
|     alignItems: 'flex-end', | ||||
|   }, | ||||
| }; | ||||
| 
 | ||||
| class BikeForm extends React.Component { | ||||
|   constructor({ bike }) { | ||||
|     super(); | ||||
|     this.state = { | ||||
|       bike, | ||||
|     }; | ||||
| 
 | ||||
|     this.handleChange = this.handleChange.bind(this); | ||||
|     this.handleSizeChange = this.handleSizeChange.bind(this); | ||||
|     this.handleSourceChange = this.handleSourceChange.bind(this); | ||||
|   } | ||||
| 
 | ||||
|   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 } }); | ||||
|   } | ||||
| 
 | ||||
|   render() { | ||||
|     const timezone = moment.tz.guess(); | ||||
|     const { | ||||
|       price, | ||||
|       claimed_at, | ||||
|       claimed_by, | ||||
|       colour, | ||||
|       cpic_searched_at, | ||||
|       created_at, | ||||
|       size, | ||||
|       serial_number, | ||||
|       source, | ||||
|       stolen, | ||||
|       stripped, | ||||
|     } = this.state.bike; | ||||
|     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 ( | ||||
|       <div> | ||||
|         <div className="mdl-grid"> | ||||
|           <div className="mdl-cell mdl-cell--3-col"> | ||||
|             <TextField | ||||
|               name="make" | ||||
|               floatingLabelText="Make" | ||||
|               hintText="Norco" | ||||
|               value={this.state.bike.make} | ||||
|               onChange={this.handleChange} | ||||
|               fullWidth | ||||
|               required | ||||
|             /> | ||||
|           </div> | ||||
|           <div className="mdl-cell mdl-cell--3-col"> | ||||
|             <TextField | ||||
|               name="price" | ||||
|               floatingLabelText="Price" | ||||
|               hintText="35.60" | ||||
|               value={this.state.bike.price} | ||||
|               onChange={this.handleChange} | ||||
|               fullWidth | ||||
|             /> | ||||
|           </div> | ||||
|           <div className="mdl-cell mdl-cell--3-col"> | ||||
|             <TextField | ||||
|               name="colour" | ||||
|               floatingLabelText="Colour" | ||||
|               hintText="orange" | ||||
|               value={this.state.bike.colour} | ||||
|               onChange={this.handleChange} | ||||
|               fullWidth | ||||
|               required | ||||
|             /> | ||||
|           </div> | ||||
|           <div className="mdl-cell mdl-cell--3-col"> | ||||
|             <Size | ||||
|               onChange={this.handleSizeChange} | ||||
|               size={this.state.bike.size} | ||||
|             /> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div className="mdl-grid"> | ||||
|           <div className="mdl-cell mdl-cell--6-col"> | ||||
|             <TextField | ||||
|               name="serial_number" | ||||
|               floatingLabelText="Serial number" | ||||
|               hintText="ab90cd23" | ||||
|               value={this.state.bike.serial_number} | ||||
|               onChange={this.handleChange} | ||||
|               fullWidth | ||||
|               required | ||||
|             /> | ||||
|           </div> | ||||
|           <div className="mdl-cell mdl-cell--6-col"> | ||||
|             <TextField | ||||
|               floatingLabelText="Created at" | ||||
|               value={createdAtFormatted} | ||||
|               fullWidth | ||||
|               readOnly | ||||
|               disabled | ||||
|             /> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div className="mdl-grid"> | ||||
|           <div className="mdl-cell mdl-cell--6-col"> | ||||
|             <TextField | ||||
|               floatingLabelText="Claimed on" | ||||
|               value={claimedAtFormatted} | ||||
|               fullWidth | ||||
|               disabled | ||||
|             /> | ||||
|           </div> | ||||
|           <div className="mdl-cell mdl-cell--6-col"> | ||||
|             <TextField | ||||
|               floatingLabelText="Claimed by" | ||||
|               value={claimed_by} | ||||
|               fullWidth | ||||
|               disabled | ||||
|               readonly | ||||
|             /> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div className="content-grid mdl-grid" style={styles.bottom}> | ||||
|           <div className="mdl-cell mdl-cell--6-col"> | ||||
|             <TextField floatingLabelText="CPIC searched" value={cpicSearchedAtFormatted} disabled /> | ||||
|           </div> | ||||
|           <div className="mdl-cell mdl-cell--4-col"> | ||||
|             <Checkbox | ||||
|               name="stolen" | ||||
|               label="Stolen" | ||||
|               labelPosition="left" | ||||
|               style={styles.checkbox} | ||||
|               value={stolen} | ||||
|               disabled | ||||
|             /> | ||||
|           </div> | ||||
|           <div className="mdl-cell mdl-cell--2-col"> | ||||
|             <FlatButton label="Check" primary /> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div className="mdl-grid" style={styles.bottom}> | ||||
|           <div className="mdl-cell mdl-cell--8-col"> | ||||
|             <Source | ||||
|               source={source} | ||||
|               onChange={this.handleSourceChange} | ||||
|             /> | ||||
|           </div> | ||||
|           <div className="mdl-cell mdl-cell--4-col"> | ||||
|             <div style={styles.block}> | ||||
|               <Checkbox | ||||
|                 name="stripped" | ||||
|                 label="Stripped" | ||||
|                 labelPosition="left" | ||||
|                 style={styles.checkbox} | ||||
|                 onCheck={this.handleChange} | ||||
|               /> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export default BikeForm; | ||||
| @ -1,12 +1,7 @@ | ||||
| import Checkbox from 'material-ui/Checkbox'; | ||||
| import React, { PropTypes } from 'react'; | ||||
| import Dialog from 'material-ui/Dialog'; | ||||
| import FlatButton from 'material-ui/FlatButton'; | ||||
| import moment from 'moment-timezone'; | ||||
| import React, { PropTypes } from 'react'; | ||||
| import TextField from 'material-ui/TextField'; | ||||
| 
 | ||||
| import Source from '../Source'; | ||||
| import Size from '../Size'; | ||||
| import BikeForm from '../BikeForm'; | ||||
| 
 | ||||
| /** | ||||
|  * A modal dialog can only be closed by selecting one of the actions. | ||||
| @ -24,26 +19,16 @@ export default class BikeModal extends React.Component { | ||||
|       bike: undefined, | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   componentWillReceiveProps(newProps) { | ||||
|     this.setState({ open: newProps.open || false, bike: newProps.bike || false }); | ||||
|   } | ||||
| 
 | ||||
|   handleClose = () => { | ||||
|     this.setState({ open: false }); | ||||
|   }; | ||||
| 
 | ||||
|   render() { | ||||
|     const styles = { | ||||
|       block: { | ||||
|         maxWidth: 250, | ||||
|       }, | ||||
|       checkbox: { | ||||
|         marginBottom: 16, | ||||
|       }, | ||||
|       bottom: { | ||||
|         alignItems: 'flex-end', | ||||
|       }, | ||||
|     }; | ||||
| 
 | ||||
|     const actions = [ | ||||
|       <FlatButton | ||||
|         label="Cancel" | ||||
| @ -58,104 +43,15 @@ export default class BikeModal extends React.Component { | ||||
|       />, | ||||
|     ]; | ||||
| 
 | ||||
|     let form; | ||||
| 
 | ||||
| 
 | ||||
|     if (this.state.bike !== undefined) { | ||||
|       const timezone = moment.tz.guess(); | ||||
|       const { | ||||
|         make, | ||||
|         price, | ||||
|         claimed_at, | ||||
|         claimed_by, | ||||
|         colour, | ||||
|         cpic_searched_at, | ||||
|         created_at, | ||||
|         size, | ||||
|         serial_number, | ||||
|         source, | ||||
|         stolen, | ||||
|         stripped } = this.state.bike; | ||||
|       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() : ''; | ||||
| 
 | ||||
|       form = ( | ||||
|         <div> | ||||
|           <div className="mdl-grid"> | ||||
|             <div className="mdl-cell mdl-cell--3-col"> | ||||
|               <TextField floatingLabelText="Make" hintText="Norco" value={make} fullWidth required /> | ||||
|             </div> | ||||
|             <div className="mdl-cell mdl-cell--3-col"> | ||||
|               <TextField floatingLabelText="Price" hintText="35.60" value={price} fullWidth /> | ||||
|             </div> | ||||
|             <div className="mdl-cell mdl-cell--3-col"> | ||||
|               <TextField floatingLabelText="Colour" hintText="orange" value={colour} fullWidth required /> | ||||
|             </div> | ||||
|             <div className="mdl-cell mdl-cell--3-col"> | ||||
|               <Size size={size} /> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div className="mdl-grid"> | ||||
|             <div className="mdl-cell mdl-cell--6-col"> | ||||
|               <TextField floatingLabelText="Serial number" hintText="ab90cd23" value={serial_number} | ||||
|                          fullWidth required /> | ||||
|             </div> | ||||
|             <div className="mdl-cell mdl-cell--6-col"> | ||||
|               <TextField floatingLabelText="Created at" value={createdAtFormatted} fullWidth readOnly disabled /> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div className="mdl-grid"> | ||||
|             <div className="mdl-cell mdl-cell--6-col"> | ||||
|               <TextField floatingLabelText="Claimed on" value={claimedAtFormatted} fullWidth disabled /> | ||||
|             </div> | ||||
|             <div className="mdl-cell mdl-cell--6-col"> | ||||
|               <TextField floatingLabelText="Claimed by" value={claimed_by} fullWidth /> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div className="content-grid mdl-grid" style={styles.bottom}> | ||||
|             <div className="mdl-cell mdl-cell--6-col"> | ||||
|               <TextField floatingLabelText="CPIC searched" value={cpicSearchedAtFormatted} disabled /> | ||||
|             </div> | ||||
|             <div className="mdl-cell mdl-cell--6-col"> | ||||
|               <Checkbox | ||||
|                 label="Stolen" | ||||
|                 labelPosition="left" | ||||
|                 style={styles.checkbox} | ||||
|                 value={stolen} | ||||
|                 disabled | ||||
|               /> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div className="mdl-grid" style={styles.bottom}> | ||||
|             <div className="mdl-cell mdl-cell--8-col"> | ||||
|               <Source source={source} /> | ||||
|             </div> | ||||
|             <div className="mdl-cell mdl-cell--4-col"> | ||||
|               <div style={styles.block}> | ||||
|                 <Checkbox | ||||
|                   label="Stripped" | ||||
|                   labelPosition="left" | ||||
|                   style={styles.checkbox} | ||||
|                   value={stripped} | ||||
|                 /> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       ); | ||||
|     } | ||||
| 
 | ||||
|     return (<div> | ||||
|       <Dialog | ||||
|         title="Edit Bike" | ||||
|         actions={actions} | ||||
|         modal | ||||
|         open={this.state.open} | ||||
|         autoScrollBodyContent | ||||
|       > | ||||
|         {form || <div>Unable to edit bike.</div>} | ||||
| 
 | ||||
|         { this.state.bike ? <BikeForm bike={this.state.bike} /> : <div>Unable to edit bike.</div>} | ||||
|       </Dialog> | ||||
|     </div>); | ||||
|   } | ||||
|  | ||||
| @ -22,20 +22,21 @@ export const friendlySize = (size) => { | ||||
| }; | ||||
| 
 | ||||
| const styles = { | ||||
|   float: 'left' | ||||
|   float: 'left', | ||||
| } | ||||
| 
 | ||||
| const Size = ({ size }) => { | ||||
| const Size = ({ size, onChange }) => { | ||||
|   const items = sizes.map(s => | ||||
|     <MenuItem value={s} primaryText={friendlySize(s)} />, | ||||
|     <MenuItem name="size" value={s} primaryText={friendlySize(s)} />, | ||||
|   ); | ||||
| 
 | ||||
|   return ( | ||||
|     <div style={styles}> | ||||
|       <SelectField | ||||
|         floatingLabelText="Size" | ||||
|         name="size" | ||||
|         value={size} | ||||
|         onChange={undefined} | ||||
|         onChange={onChange} | ||||
|         fullWidth | ||||
|       > | ||||
|         <MenuItem value={null} primaryText="" /> | ||||
| @ -47,6 +48,7 @@ const Size = ({ size }) => { | ||||
| 
 | ||||
| Size.propTypes = { | ||||
|   size: PropTypes.string, | ||||
|   onChange: PropTypes.function, | ||||
| }; | ||||
| 
 | ||||
| export default Size; | ||||
|  | ||||
| @ -17,7 +17,7 @@ export const friendly = (s) => { | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| const Source = ({ source }) => { | ||||
| const Source = ({ source, onChange }) => { | ||||
|   const items = sources.map(s => | ||||
|     <MenuItem value={s} primaryText={friendly(s)} />, | ||||
|   ); | ||||
| @ -27,7 +27,7 @@ const Source = ({ source }) => { | ||||
|       <SelectField | ||||
|         floatingLabelText="Source" | ||||
|         value={source} | ||||
|         onChange={undefined} | ||||
|         onChange={onChange} | ||||
|         fullWidth | ||||
|       > | ||||
|         <MenuItem value={null} primaryText="" /> | ||||
| @ -39,6 +39,7 @@ const Source = ({ source }) => { | ||||
| 
 | ||||
| Source.propTypes = { | ||||
|   source: PropTypes.string, | ||||
|   onChange: PropTypes.function | ||||
| }; | ||||
| 
 | ||||
| export default Source; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user