index.js 12.6 KB
import React, {Component} from 'react';
import PropTypes from 'prop-types'

import ProfilationStep from './ProfilationStep'

import * as SelectActionCreators from '../actions/profilationSelect'
import {connect} from 'react-redux';

import {NavLink} from 'react-router-dom';
import { Motion, spring, presets } from 'react-motion';
import  LemaApi  from '../../service/service.js';

import Header from "../../components/header/index";

class Profilation extends Component {
  constructor(props) {
    super(props);


    this.state = {
      steps: props.steps,
      activeStep: props.activeStep,
      scrollTop: 0,
      tabIndex:1,
      visible: false,
      showLoader: true      
    };

    this.handleTab=this.handleTab.bind(this)    
  }

  componentWillReceiveProps(nextProps) {

    if (nextProps.steps !== this.state.steps) {
      this.setState({steps: nextProps.steps, activeStep: nextProps.activeStep}, () => {
        setTimeout(() => {
          this.scrollTo('step' + nextProps.activeStep);
          
        }, 200);
      });
    }
  }

  handleTab(e){
    if(e.keyCode===9){
              e.preventDefault()
              e.stopPropagation()

             
              var newTab=this.props.tabIndex
              var direction=1
              if(e.shiftKey){
                direction=-1
              }

              newTab=newTab+direction
              var maxtab=3
              for (var i = 1; i <= 12; i++) {
                        if(document.querySelector('*[tabindex="'+i+'"]')!==null){
                          maxtab=i;
                        }
                      }
            
              if(document.querySelector('*[tabindex="'+newTab+'"]')!==null){
                   if(document.querySelector('*[tabindex="'+this.props.tabIndex+'"]')!==null){
                    document.querySelector('*[tabindex="'+this.props.tabIndex+'"]').blur()
                  }
                   document.querySelector('*[tabindex="'+newTab+'"]').focus()
                
                 
              }
              else{
                  
                  //se non esiste
                  var nexttab=newTab;
                  if(document.querySelector('*[tabindex="'+newTab+'"]')===null){
                    if(e.shiftKey){
                      for (var x = newTab; x > 1; x--) {
                      if(document.querySelector('*[tabindex="'+x+'"]')!==null){
                          nexttab=x;
                          break;
                        }
                    }
                    }else{
                      for (var j = newTab; j <= maxtab; j++) {
                      if(document.querySelector('*[tabindex="'+j+'"]')!==null){
                          nexttab=j;
                          break;
                        }
                    }
                    }
                    
                    if(nexttab===newTab){
                      if(e.shiftKey){
                        newTab=maxtab

                      }
                      else{
                        newTab=1
                      }
                    }else{
                      newTab=nexttab
                    }
                    
                  }
                  if(document.querySelector('*[tabindex="'+this.props.tabIndex+'"]')!==null){
                    document.querySelector('*[tabindex="'+this.props.tabIndex+'"]').blur()
                  }
                   
                   document.querySelector('*[tabindex="'+newTab+'"]').focus()
                
              }

              this.props.updateStoreValue('tabIndex',newTab)

          }
  }
 
  componentDidMount() {

     // Servizio per interazione con il server
     var lemaApi = new LemaApi();
        
     // Carico i dati dell'applicazione
     var promiseConfigData = lemaApi.loadWebClientConfigData();
     var promiseSubscriptionSession = lemaApi.getSubscriptionSession();

     // All promises are OK, load profilation
     Promise.all([promiseConfigData, promiseSubscriptionSession]).then(
         () => {                     
                // Get profilation if exists
            lemaApi.getProfilationData().then(data => {    
                console.clear();                        

                //  Ricostruisco lo stato della profilazione con i dati salvati
                var isCompleteStep2 = (data.profilation.expend && data.profilation.period) &&
                    (data.profilation.light || data.profilation.gas);
                
                var savedSteps = [
                    {
                        isComplete: data.profilation.job && data.profilation.service,
                        job: data.profilation.job,
                        service: data.profilation.service
                    }, {
                        isComplete: isCompleteStep2,
                        expend: data.profilation.expend,
                        period: data.profilation.period,
                        light: data.profilation.light,
                        gas: data.profilation.gas
                    }, {
                        isComplete: data.profilation.environment ? true : false,
                        environment: data.profilation.environment
                    }, {
                        isComplete: data.profilation.flexibility ? true: false,
                        flexibility: data.profilation.flexibility
                    }, {
                        isComplete: data.profilation.customizable ? true : false,
                        customizable: data.profilation.customizable
                    }
                ]    
                                    
                // pattern corretto per setState: si passa una funzione invece dell'oggetto
                this.setState(prevState => {
                    return {                                 
                        visible: true, 
                        showLoader: false  
                    };
                });  
                this.props.updateStoreValue('steps',savedSteps)                                                                  
            })                
            .catch(error =>
            {
                console.error("Not data bucket found");
                this.setState(prevState => {
                    return {                                 
                        visible: true, 
                        showLoader: false  
                    };
                });  
            });    
        });                      
    
      document.querySelector('.ProfilationApp').addEventListener('keydown',e=>this.handleTab(e))


    window.onload = () => {
      setTimeout(() => {
        
        window.scrollTo(0, -1);
      }, 0);
    }
    document.body.classList.add("stop-scrolling");
    document.body.classList.remove("profilation-body", "no-close");

    const wheelEvent = 'onwheel' in document ? 'wheel' : document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll';
    
    window.addEventListener(wheelEvent, this.handleScroll);
  }

  componentWillUnmount() {
    const wheelEvent = 'onwheel' in document ? 'wheel' : document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll';
    
    window.removeEventListener(wheelEvent, this.handleScroll);
    //window.removeEventListener("wheel", this.handleScroll);

  }

  handleScroll = (e) => {
    if(this.timer !== null) {
      clearTimeout(this.timer);        
    }
    if (this.locked === true) {
      return false;
    }
    const delta=e.wheelDelta
    

    
    this.timer = setTimeout(() => {
      if (delta < 0 && this.state.activeStep >= 0 && this.state.activeStep < this.state.steps.length - 1) {
        if (this.state.steps[this.state.activeStep].isComplete)
          this.activeStep(this.state.activeStep + 1);
      } else if (delta > 0) {
        this.state.activeStep > 0 && this.activeStep(this.state.activeStep - 1);
      }
    }, 50);

    return false;
  };

  activeStep = (activeStep) => {
    if (activeStep === this.state.activeStep) return true;

    this.props.updateStoreValue('progressBar',activeStep)
    this.setState({activeStep: activeStep}, () => {
      this.props.updatePropValue(this.state.steps, activeStep);
      this.scrollTo(`step${activeStep}`);
    });
  }

  updateStep = (index, step) => {
    let state = {...this.state};
    let steps = state.steps;
    if (index === 0 && steps[0].service !== step.service) {
      steps[1].light = "";
      steps[1].gas = "";
      steps[1].completed = false;
    }
    steps[index] = step;
    this.setState({steps: steps}, () => {
      this.props.updatePropValue(steps, this.state.activeStep);
    });

    if (step.isComplete === true) {
      
      //save profilation data at the end of a step
      this.saveSteps();
      if (index+1 === steps.length) {
        //COMPLETED, SEND
      } else {
        if(index!==1){

          this.activeStep(index+1);
        }
      }
    }
  }

  saveSteps = () => {
     this.props.updateStoreValue('progressBar',5)
     this.props.updateStoreValue('progressBar',5);
     return null;
  }

  scrollTo = (elementId) => {
    this.locked = true;

    const bodyRect = document.body.getBoundingClientRect()
    const paddingTop = window.getComputedStyle(document.getElementById('profilation'), null).getPropertyValue('padding-top');

    var el = document.getElementById(elementId);
    if (el != null) {
      var top = el.getBoundingClientRect().top - bodyRect.top;
      
      this.setState({scrollTop: top - parseInt(paddingTop, 10)});   
      window.scrollTo(0, top - parseInt(paddingTop, 10));
    }

    setTimeout(() => {
      this.locked = false;
    }, 200)
  }

  isComplete = () => {
    let isC = true;
    let steps = this.state.steps || [];
    if (steps.length === 0) return false;

    steps.forEach(s => {
      if (!s.isComplete) isC = false;
    });

    return isC;
  }

  render() {
    const isComplete = this.isComplete();
    const stepComponents = (this.state.steps || []).map((step, index) => ((step.isComplete || this.state.activeStep === index || (index > 0 && this.state.steps[index -1].isComplete)) && <ProfilationStep
      key={index}
      index={index}
      step={step}
      isActive={this.state.activeStep === index}
      updatePropValue={this.updateStep}
      activeStep={this.activeStep}
      completeSteps={this.state.steps}
      />));
      

    return (
      <div className='ProfilationApp' id='profilation'>      
      <Header history={this.props.history} pathname={this.props.history.location.pathname}/>
        
        {this.state.showLoader && <AppSpinner/>}

        {this.state.visible && stepComponents}

          {isComplete && !this.state.showLoader && <div className='ProfilationStep'>
            <NavLink to={`/loader`} activeClassName="active" className='btn_go'>
              <button tabIndex={12} className="btn btn__red" onClick={() => this.saveSteps()}>MOSTRAMI LA SOLUZIONE</button>
            </NavLink>
          </div>}
        <Motion
          style={{
            scrollTop: spring(this.state.scrollTop, presets.noWobble)
          }}
        >
          {currentStyles => {
            return <WindowScrollSink scrollTop={currentStyles.scrollTop} />
              
          }}
        </Motion>
      </div>
    )
  }
}

class WindowScrollSink extends Component {
    componentDidUpdate (prevProps) {
        if (prevProps.scrollTop !== this.props.scrollTop) {
            return window.scrollTo(0, this.props.scrollTop);
        }
    }

  render () {
    return null
  }
}


class AppSpinner extends Component {
  render () {
      return ( 
        <div>
            <div className="verify-loader loader_spinner"></div>
        </div>
    )
  }
}

const mapStateToProps = state => {
  return {
    tabIndex: state.ProfilationSelectReducer.tabIndex,
    profilationStepTwoError: state.ProfilationSelectReducer.profilationStepTwoError,
    steps: state.ProfilationSelectReducer.steps,
    activeStep: state.ProfilationSelectReducer.activeStep || 0,
    
  }
};

const mapDispatchToProps = dispatch => ({
  updatePropValue: (steps, activeStep) => dispatch(SelectActionCreators.changeValue(steps, activeStep)),
  updateStoreValue: (prop,value) => 
    dispatch(SelectActionCreators.changeProp(prop,value)),


    

});

Profilation.propTypes = {
  steps: PropTypes.array.isRequired,
  activeStep: PropTypes.number.isRequired,
  updatePropValue: PropTypes.func.isRequired
}

export default connect(mapStateToProps, mapDispatchToProps)(Profilation);