UNPKG

reacts-test-lmbuffetti

Version:

Simple starter package for Redux with React and Babel support

322 lines (294 loc) 10.7 kB
import React, { Component } from 'react'; import ReactDOM from 'react-dom'; // component that renders a single product var ProductRow = React.createClass({ render: function() { return ( <tr> <td>{this.props.product.name}</td> <td>{this.props.product.description}</td> <td>€ {parseFloat(this.props.product.price).toFixed(2)}</td> <td>{this.props.product.category_name}</td> <td> <a href='#' onClick={() => this.props.changeAppMode('readOne', this.props.product.id)} className='btn btn-info m-r-1em'> Read </a> <a href='#' onClick={() => this.props.changeAppMode('update', this.props.product.id)} className='btn btn-primary m-r-1em'> Edit </a> <a onClick={() => this.props.changeAppMode('delete', this.props.product.id)} className='btn btn-danger'> Delete </a> </td> </tr> ); } }); // component for the whole products table var ProductsTable = React.createClass({ render: function() { var rows = this.props.products .map(function(product, i) { return ( <ProductRow key={i} product={product} changeAppMode={this.props.changeAppMode} /> ); }.bind(this)); return( !rows.length ? <div className='alert alert-danger'>No products found.</div> : <table className='table table-bordered table-hover'> <thead> <tr> <th>Name</th> <th>Description</th> <th>Price</th> <th>Category</th> <th>Action</th> </tr> </thead> <tbody> {rows} </tbody> </table> ); } }); // component that contains all the logic and other smaller components // that form the Read Products view var TopActionsComponent = React.createClass({ render: function() { return ( <div> <a href='#' onClick={() => this.props.changeAppMode('create')} className='btn btn-primary margin-bottom-1em'> Create product </a> </div> ); } }); var ReadProductsComponent = React.createClass({ getInitialState: function() { return { products: [] }; }, // on mount, fetch all products and stored them as this component's state componentDidMount: function() { this.serverRequest = $.get("api/read_all_products.php", function (products) { this.setState({ products: JSON.parse(products) }); }.bind(this)); }, // on unmount, kill product fetching in case the request is still pending componentWillUnmount: function() { this.serverRequest.abort(); }, render: function() { // list of products var filteredProducts = this.state.products; $('.page-header h1').text('Read Products'); return ( <div className='overflow-hidden'> <TopActionsComponent changeAppMode={this.props.changeAppMode} /> <ProductsTable products={filteredProducts} changeAppMode={this.props.changeAppMode} /> </div> ); } }); var MainApp = React.createClass({ getInitialState: function() { return { currentMode: 'read', productId: null }; }, changeAppMode: function(newMode, productId){ this.setState({currentMode: newMode}); if(productId !== undefined){ this.setState({productId: productId}); } }, render: function() { var modeComponent = <ReadProductsComponent changeAppMode={this.changeAppMode} />; switch(this.state.currentMode){ case 'read': break; case 'create': modeComponent = <CreateProductComponent changeAppMode={this.changeAppMode}/>; break; default: break; } return modeComponent; } }); var CreateProductComponent = React.createClass({ getInitialState: function() { return { categories: [], selectedCategoryId: -1, name: '', description: '', price: '', successCreation: null }; }, componentDidMount: function() { this.serverRequest = $.get("api/read_all_categories.php", function (categories) { this.setState({ categories: JSON.parse(categories) }); }.bind(this)); $('.page-header h1').text('Create product'); }, componentWillUnmount: function() { this.serverRequest.abort(); }, // handle category change onCategoryChange: function(e) { this.setState({selectedCategoryId: e.target.value}); }, // handle name change onNameChange: function(e) { this.setState({name: e.target.value}); }, // handle description change onDescriptionChange: function(e) { this.setState({description: e.target.value}); }, // handle price change onPriceChange: function(e) { this.setState({price: e.target.value}); }, onSave: function(e){ $.post("api/create_product.php", { name: this.state.name, description: this.state.description, price: this.state.price, category_id: this.state.selectedCategoryId }, function(res){ this.setState({successCreation: res}); this.setState({name: ""}); this.setState({description: ""}); this.setState({price: ""}); this.setState({selectedCategoryId: -1}); }.bind(this) ); e.preventDefault(); }, render: function() { // make categories as option for the select tag. var categoriesOptions = this.state.categories.map(function(category){ return ( <option key={category.id} value={category.id}>{category.name}</option> ); }); /* - tell the user if a product was created - tell the user if unable to create product - button to go back to products list - form to create a product */ return ( <div> { this.state.successCreation == "true" ? <div className='alert alert-success'> Product was saved. </div> : null } { this.state.successCreation == "false" ? <div className='alert alert-danger'> Unable to save product. Please try again. </div> : null } <a href='#' onClick={() => this.props.changeAppMode('read')} className='btn btn-primary margin-bottom-1em'> Read Products </a> <form onSubmit={this.onSave}> <table className='table table-bordered table-hover'> <tbody> <tr> <td>Name</td> <td> <input type='text' className='form-control' value={this.state.name} required onChange={this.onNameChange} /> </td> </tr> <tr> <td>Description</td> <td> <textarea type='text' className='form-control' required value={this.state.description} onChange={this.onDescriptionChange}> </textarea> </td> </tr> <tr> <td>Price ($)</td> <td> <input type='number' step="0.01" className='form-control' value={this.state.price} required onChange={this.onPriceChange}/> </td> </tr> <tr> <td>Category</td> <td> <select onChange={this.onCategoryChange} className='form-control' value={this.state.selectedCategoryId}> <option value="-1">Select category...</option> {categoriesOptions} </select> </td> </tr> <tr> <td></td> <td> <button className='btn btn-primary' onClick={this.onSave}>Save</button> </td> </tr> </tbody> </table> </form> </div> ); } }); ReactDOM.render( <MainApp />, document.getElementById('content') );