Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import _ from 'lodash';
- import React, {Component} from 'react';
- import ProductError from './ProductError';
- import ProductForm from './ProductForm';
- import ProductPricing from './ProductPricing';
- import {ScaleLoader} from 'react-spinners';
- class Product extends Component {
- constructor(props) {
- super(props);
- this.state = {
- configuration: this.props.configuration,
- authToken: this.props.authToken,
- values: this.props.values || [],
- price: this.props.price,
- quantity: this.props.quantity,
- loading: false,
- recalculated: false,
- formRef: null,
- inputs: [],
- errors: []
- };
- this.submitConfig = this.submitConfig.bind(this);
- this.onChange = this.onChange.bind(this);
- this.recalculate = this.recalculate.bind(this);
- this.formRef = this.formRef.bind(this);
- this.resetValidation = this.resetValidation.bind(this);
- this.onRequiredChange = this.onRequiredChange.bind(this);
- this.addInput = this.addInput.bind(this);
- }
- static openSectionWithErrors(form) {
- for (let el of form.elements) {
- Product.checkElementValidity(el);
- }
- return form.reportValidity();
- }
- static checkElementValidity(element) {
- if (element.validity && !element.validity.valid) {
- let section = element.closest(".collapse");
- if (section && !$(section).hasClass("show")) {
- $(section).addClass("show");
- }
- }
- }
- static handleSuccess(res, callback) {
- res.json().then(json => {
- callback(json);
- });
- }
- handleError(res) {
- res.json().then(json => {
- this.setState(Object.assign({}, ...this.state, {
- errors: json,
- loading: false
- }))
- });
- }
- renderErrors() {
- const { errors } = this.state;
- return errors.map((msg, i) => {
- return <ProductError key={i} errorMsg={msg}/>;
- });
- }
- onChange(value, changedState) {
- if (value.variable.value === "") {
- this.removeValue(value, changedState);
- } else {
- this.addValue(value, changedState);
- }
- }
- onRequiredChange(value) {
- const { formRef } = this.state;
- this.state.values = [];
- this.onChange(value);
- this.postForm(formRef, "/product/recalculate.json", json => {
- for (const input of this.state.inputs) {
- if (!input.state.rules.get("Required")) {
- input.resetValue();
- }
- }
- this.setState(Object.assign({}, ...this.state, {
- configuration: json.configuration,
- loading: false
- }))
- });
- }
- resetValidation() {
- this.setState(Object.assign({}, ...this.state, {
- recalculated: false
- }));
- }
- addValue(value, changedState) {
- this.removeValue(value);
- this.state.values = [...this.state.values, {
- charDesc: value.text.name,
- charText: value.text.value,
- charName: value.variable.name,
- charValue: value.variable.value
- }];
- if (changedState) {
- this.setState(Object.assign({}, ...this.state, changedState));
- }
- }
- removeValue(value, changedState) {
- _.remove(this.state.values, v => {
- return v.charName === value.variable.name
- });
- if (changedState) {
- this.setState(Object.assign({}, ...this.state, changedState));
- }
- }
- recalculate(e) {
- e.preventDefault();
- const { formRef } = this.state;
- if (!formRef.checkValidity()) {
- return Product.openSectionWithErrors(formRef);
- }
- this.postForm(formRef, "/product/recalculate.json", json => {
- this.setState(Object.assign({}, ...this.state, {
- price: json.price,
- recalculated: true,
- configuration: json.configuration,
- loading: false
- }))
- });
- }
- submitConfig(e) {
- e.preventDefault();
- let { formRef } = this.state;
- this.postForm(formRef, "/product/submit.json", json => {
- window.location.href = json.url;
- });
- }
- postForm(form, endpoint, callback) {
- const data = new FormData(form);
- this.setState(Object.assign({}, ...this.state, {
- loading: true,
- errors: []
- }));
- data.append("configuration", JSON.stringify(this.state.values));
- window.fetch(endpoint, {
- method: "POST",
- credentials: "include",
- body: data
- }).then(res => {
- if (res.ok) {
- Product.handleSuccess(res, callback);
- } else {
- this.handleError(res);
- }
- });
- }
- renderPricing() {
- const { price } = this.state;
- return (
- <ProductPricing priceSheet={price.sheet}/>
- );
- }
- renderSpinner() {
- return (
- <div className="spinner-wrapper">
- <ScaleLoader color="#cc0000" loading={this.state.loading}/>
- </div>
- )
- }
- formRef(form) {
- this.state.formRef = form;
- }
- addInput(input) {
- this.state.inputs = [...this.state.inputs, input];
- }
- render() {
- const { configuration, quantity, values, loading, recalculated } = this.state;
- return (
- <div>
- {this.renderErrors()}
- {this.renderPricing()}
- <ProductForm
- onSubmit={this.submitConfig}
- onChange={this.onChange}
- onRequiredChange={this.onRequiredChange}
- resetValidation={this.resetValidation}
- formRef={this.formRef}
- addInput={this.addInput}
- quantity={quantity}
- values={values}
- recalculate={this.recalculate}
- recalculated={recalculated}
- configuration={configuration}/>
- {this.renderSpinner()}
- {loading ? <div className="content-fade"/> : null}
- </div>
- );
- }
- }
- export default Product;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement