Advertisement
Someluck

Product.jsx

Jun 17th, 2019
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import _ from 'lodash';
  2. import React, {Component} from 'react';
  3. import ProductError from './ProductError';
  4. import ProductForm from './ProductForm';
  5. import ProductPricing from './ProductPricing';
  6. import {ScaleLoader} from 'react-spinners';
  7.  
  8. class Product extends Component {
  9.     constructor(props) {
  10.         super(props);
  11.         this.state = {
  12.             configuration: this.props.configuration,
  13.             authToken: this.props.authToken,
  14.             values: this.props.values || [],
  15.             price: this.props.price,
  16.             quantity: this.props.quantity,
  17.             loading: false,
  18.             recalculated: false,
  19.             formRef: null,
  20.             inputs: [],
  21.             errors: []
  22.         };
  23.  
  24.         this.submitConfig = this.submitConfig.bind(this);
  25.         this.onChange = this.onChange.bind(this);
  26.         this.recalculate = this.recalculate.bind(this);
  27.         this.formRef = this.formRef.bind(this);
  28.         this.resetValidation = this.resetValidation.bind(this);
  29.         this.onRequiredChange = this.onRequiredChange.bind(this);
  30.         this.addInput = this.addInput.bind(this);
  31.     }
  32.  
  33.     static openSectionWithErrors(form) {
  34.         for (let el of form.elements) {
  35.             Product.checkElementValidity(el);
  36.         }
  37.  
  38.         return form.reportValidity();
  39.     }
  40.  
  41.     static checkElementValidity(element) {
  42.         if (element.validity && !element.validity.valid) {
  43.             let section = element.closest(".collapse");
  44.  
  45.             if (section && !$(section).hasClass("show")) {
  46.                 $(section).addClass("show");
  47.             }
  48.         }
  49.     }
  50.  
  51.     static handleSuccess(res, callback) {
  52.         res.json().then(json => {
  53.             callback(json);
  54.         });
  55.     }
  56.  
  57.     handleError(res) {
  58.         res.json().then(json => {
  59.             this.setState(Object.assign({}, ...this.state, {
  60.                 errors: json,
  61.                 loading: false
  62.             }))
  63.         });
  64.     }
  65.  
  66.     renderErrors() {
  67.         const { errors } = this.state;
  68.  
  69.         return errors.map((msg, i) => {
  70.             return <ProductError key={i} errorMsg={msg}/>;
  71.         });
  72.     }
  73.  
  74.     onChange(value, changedState) {
  75.         if (value.variable.value === "") {
  76.             this.removeValue(value, changedState);
  77.         } else {
  78.             this.addValue(value, changedState);
  79.         }
  80.     }
  81.  
  82.     onRequiredChange(value) {
  83.         const { formRef } = this.state;
  84.  
  85.         this.state.values = [];
  86.         this.onChange(value);
  87.         this.postForm(formRef, "/product/recalculate.json", json => {
  88.             for (const input of this.state.inputs) {
  89.                 if (!input.state.rules.get("Required")) {
  90.                     input.resetValue();
  91.                 }
  92.             }
  93.  
  94.             this.setState(Object.assign({}, ...this.state, {
  95.                 configuration: json.configuration,
  96.                 loading: false
  97.             }))
  98.         });
  99.     }
  100.  
  101.     resetValidation() {
  102.         this.setState(Object.assign({}, ...this.state, {
  103.             recalculated: false
  104.         }));
  105.     }
  106.  
  107.     addValue(value, changedState) {
  108.         this.removeValue(value);
  109.  
  110.         this.state.values = [...this.state.values, {
  111.             charDesc: value.text.name,
  112.             charText: value.text.value,
  113.             charName: value.variable.name,
  114.             charValue: value.variable.value
  115.         }];
  116.  
  117.         if (changedState) {
  118.             this.setState(Object.assign({}, ...this.state, changedState));
  119.         }
  120.     }
  121.  
  122.     removeValue(value, changedState) {
  123.         _.remove(this.state.values, v => {
  124.             return v.charName === value.variable.name
  125.         });
  126.  
  127.         if (changedState) {
  128.             this.setState(Object.assign({}, ...this.state, changedState));
  129.         }
  130.     }
  131.  
  132.     recalculate(e) {
  133.         e.preventDefault();
  134.         const { formRef } = this.state;
  135.  
  136.         if (!formRef.checkValidity()) {
  137.             return Product.openSectionWithErrors(formRef);
  138.         }
  139.  
  140.         this.postForm(formRef, "/product/recalculate.json", json => {
  141.             this.setState(Object.assign({}, ...this.state, {
  142.                 price: json.price,
  143.                 recalculated: true,
  144.                 configuration: json.configuration,
  145.                 loading: false
  146.             }))
  147.         });
  148.     }
  149.  
  150.     submitConfig(e) {
  151.         e.preventDefault();
  152.         let { formRef } = this.state;
  153.  
  154.         this.postForm(formRef, "/product/submit.json", json => {
  155.             window.location.href = json.url;
  156.         });
  157.     }
  158.  
  159.     postForm(form, endpoint, callback) {
  160.         const data = new FormData(form);
  161.         this.setState(Object.assign({}, ...this.state, {
  162.             loading: true,
  163.             errors: []
  164.         }));
  165.  
  166.         data.append("configuration", JSON.stringify(this.state.values));
  167.         window.fetch(endpoint, {
  168.             method: "POST",
  169.             credentials: "include",
  170.             body: data
  171.         }).then(res => {
  172.             if (res.ok) {
  173.                 Product.handleSuccess(res, callback);
  174.             } else {
  175.                 this.handleError(res);
  176.             }
  177.         });
  178.     }
  179.  
  180.  
  181.     renderPricing() {
  182.         const { price } = this.state;
  183.  
  184.         return (
  185.             <ProductPricing priceSheet={price.sheet}/>
  186.         );
  187.     }
  188.  
  189.     renderSpinner() {
  190.         return (
  191.             <div className="spinner-wrapper">
  192.                 <ScaleLoader color="#cc0000" loading={this.state.loading}/>
  193.             </div>
  194.         )
  195.     }
  196.  
  197.     formRef(form) {
  198.         this.state.formRef = form;
  199.     }
  200.  
  201.     addInput(input) {
  202.         this.state.inputs = [...this.state.inputs, input];
  203.     }
  204.  
  205.     render() {
  206.         const { configuration, quantity, values, loading, recalculated } = this.state;
  207.  
  208.         return (
  209.             <div>
  210.                 {this.renderErrors()}
  211.                 {this.renderPricing()}
  212.                 <ProductForm
  213.                     onSubmit={this.submitConfig}
  214.                     onChange={this.onChange}
  215.                     onRequiredChange={this.onRequiredChange}
  216.                     resetValidation={this.resetValidation}
  217.                     formRef={this.formRef}
  218.                     addInput={this.addInput}
  219.                     quantity={quantity}
  220.                     values={values}
  221.                     recalculate={this.recalculate}
  222.                     recalculated={recalculated}
  223.                     configuration={configuration}/>
  224.                 {this.renderSpinner()}
  225.                 {loading ? <div className="content-fade"/> : null}
  226.             </div>
  227.         );
  228.     }
  229. }
  230.  
  231. export default Product;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement