containers/Bets/index.js

import React, { Component } from 'react';
import { connect } from 'react-redux';

import MarketsHeader from '../../components/MarketsHeader';
import OddsTable from '../../components/OddsTable';

import Betslip from '../Betslip';
import Constants, { GAME_TYPE, MINIMUM_TIME_BETWEEN_TWO_KICK_OFF } from '../../constants';
import {
  getRoundRequest, setSelectedMarket, setSelectedSubselection,
  toggleSelectedOdds, setStakes, toggleBetslip, setSelectedLeague, setMarkets,
  kickOffRequest, getTurboRoundRequest, closeModal, changePage, openModal, fetchStatistics,
} from '../../reducers';
import {
  getActiveMarkets, getSelectedMarket, getSelectedSubselection, getInitialBetsLoaded,
  getSelectedLeague, getRoundLoading, getMatches, getOdds, getLeagues, getGameType, showKickOff,
  getInitialTurboBetsLoaded,
  getHaveLiveMatches,
  getRoundId,
  getStatistics,
} from '../../store/bets';
import {
  getCurrentPage,
  getActiveModal,
  getUser,
  getPlacebetBackupLogin,
} from '../../store/common';
import {
  getIsLoadingPlaceBet,
  getPlacedSelections,
  getPlacedSelectionsTurbo,
  getSelectedOdds,
} from '../../store/placebet';

const mapToProps = (state) => ({
  markets: getActiveMarkets(state),
  selectedMarket: getSelectedMarket(state),
  selectedOdds: getSelectedOdds(state),
  selectedSubselection: getSelectedSubselection(state),
  initialBetsLoaded: getInitialBetsLoaded(state),
  selectedLeague: getSelectedLeague(state),
  currentPage: getCurrentPage(state),
  matches: getMatches(state),
  roundLoading: getRoundLoading(state),
  roundId: getRoundId(state),
  odds: getOdds(state),
  leagues: getLeagues(state),
  gameType: getGameType(state),
  showKickOff: showKickOff(state),
  initialTurboBetsLoaded: getInitialTurboBetsLoaded(state),
  activeModal: getActiveModal(state),
  user: getUser(state),
  placebetBackupLogin: getPlacebetBackupLogin(state),
  haveLiveMatches: getHaveLiveMatches(state),
  isLoadingPlaceBet: getIsLoadingPlaceBet(state),
  placedSelections: getPlacedSelections(state),
  placedSelectionsTurbo: getPlacedSelectionsTurbo(state),
  statistics: getStatistics(state),
});

const actionsToProps = (dispatch) => ({
  getRound: (payload) => dispatch(getRoundRequest(payload)),
  setSelectedMarket: (payload) => dispatch(setSelectedMarket(payload)),
  setSelectedSubselection: (payload) => dispatch(setSelectedSubselection(payload)),
  toggleSelectedOdds: (payload) => dispatch(toggleSelectedOdds(payload)),
  setStakes: (payload) => dispatch(setStakes(payload)),
  toggleBetslip: (payload) => dispatch(toggleBetslip(payload)),
  setSelectedLeague: (payload) => dispatch(setSelectedLeague(payload)),
  setMarkets: (payload) => dispatch(setMarkets(payload)),
  getTurboRound: (payload) => dispatch(getTurboRoundRequest(payload)),
  kickOff: (payload) => dispatch(kickOffRequest(payload)),
  closeModal: (payload) => dispatch(closeModal(payload)),
  changePage: (payload) => dispatch(changePage(payload)),
  openModal: (payload) => dispatch(openModal(payload)),
  fetchStatistics: (payload) => dispatch(fetchStatistics(payload)),
});

/**
 * @class
 * @property {object} props
 * @property {Array} props.markets All markets data
 * @property {object} props.selectedMarket Selected market informations
 * @property {Array} props.selectedOdds Array of selected odds
 * @property {number} props.selectedSubselection Index of selected subselection
 * @property {object} props.selectedLeague Selected league informations
 * @property {boolean} props.initialBetsLoaded Indicate is round API is fatched once
 * @property {string} props.currentPage Indicate current page
 * @property {Array} props.matches Matches informations
 * @property {boolean} props.roundLoading Represent is round API fetch
 * @property {object} props.odds Contain all odds
 * @property {Array} props.leagues Contain all leagues
 * @property {Array} props.gameType Game type Classic/Turbo
 * @property {boolean} props.showKickOff Show kick off button
 * @property {object} props.user User Data
 *
 * @property {Function} props.getRound Get round data from API
 * @property {Function} props.setSelectedMarket Change selected market
 * @property {Function} props.setSelectedSubselection Change selected subselection
 * @property {Function} props.toggleSelectedOdds Toggle selected odds
 * @property {Function} props.setStakes Change stakes in betslip
 * @property {Function} props.toggleBetslip Toggle betslip modal
 * @property {Function} props.setSelectedLeague Change selected league
 * @property {Function} props.setMarkets Setup parkets for selected league
 * @property {Function} props.getTurboRound Get turbo round data
 * @property {Function} props.kickOff Get turbo live data
 */
class Bets extends Component {
  /**
   * Call initial round API call and
   * check if selected league exist on live page
   *
   * @returns {void}
   */
  componentDidMount() {
    if (this.props.initialBetsLoaded === false && this.props.gameType === GAME_TYPE.CLASSIC) {
      this.props.getRound({
        leagueSelection: true,
        placebetBackupLogin: this.props.placebetBackupLogin,
        haveGameTypeChanged: this.props.selectedOdds.filter((x) => x.gameType
          === GAME_TYPE.TURBO).length > 0,
      });
    } else if (this.props.initialTurboBetsLoaded === false
      && this.props.gameType === GAME_TYPE.TURBO
      && this.props.user
      && this.props.user.turboEnabled) {
      this.props.getTurboRound({
        haveGameTypeChanged: !this.sameOdds(this.props.odds, this.props.selectedOdds),
      });
    }

    if (this.props.selectedLeague.enabled === 0) {
      const index = this.props.leagues.findIndex((l) => l.enabled === 1);
      this.props.setSelectedLeague({
        league: this.props.leagues[index],
        type: GAME_TYPE.CLASSIC,
        index,
      });
    }
  }

  /**
   * Setup markets when leage is changed
   *
   * @param {object} prevProps
   */
  componentDidUpdate(prevProps) {
    if (this.props.selectedLeague.id !== prevProps.selectedLeague.id) {
      this.props.setMarkets();
    }
  }

  handleKickOff = () => {
    const time = Date.now();
    if ((this.lastKickOff === undefined
      || time - this.lastKickOff >= MINIMUM_TIME_BETWEEN_TWO_KICK_OFF)
      && this.props.isLoadingPlaceBet === false) {
      this.props.kickOff();
      this.lastKickOff = time;
    }
  }

  /**
   * Check if odds changed
   *
   * @function
   * @param {Array} odds Odds for leagues
   * @param {Array} selectedOdds
   * @returns {boolean}
   */
  sameOdds = (odds, selectedOdds) => {
    for (let i = 0; i < selectedOdds.length; i += 1) {
      const sOdd = selectedOdds[i];
      if (sOdd.odd !== odds[sOdd.league][sOdd.matchId][sOdd.selectionId]) {
        return false;
      }
    }
    return true;
  }

  /**
   * Render
   *
   * @see module:MarketsHeader
   * @see module:OddsTable
   * @see Betslip
   * @returns {view}
   */
  render() {
    const isCorrectScoreSelected = this.props.selectedMarket
      && this.props.selectedMarket.correctScore === true;
    return (
      this.props.roundLoading || !this.props.markets
        ? <div className="loading-wrap sm"><div className="loading-item" /></div>
        : (
          <>
            <MarketsHeader
              markets={this.props.markets}
              isCorrectScoreSelected={isCorrectScoreSelected}
              selectedMarket={this.props.selectedMarket}
              setSelectedMarket={this.props.setSelectedMarket}
              setSelectedSubselection={this.props.setSelectedSubselection}
              selectedSubselection={this.props.selectedSubselection}
              selectedLeague={this.props.selectedLeague}
              gameType={this.props.gameType}
            />

            {this.props.selectedLeague && this.props.odds
              && (
                <OddsTable
                  matches={this.props.matches[this.props.selectedLeague.id]}
                  selectedLeague={this.props.selectedLeague}
                  odds={this.props.odds[this.props.selectedLeague.id]}
                  selectedOdds={this.props.selectedOdds}
                  toggleSelectedOdds={this.props.toggleSelectedOdds}
                  isCorrectScoreSelected={isCorrectScoreSelected}
                  selectedMarket={this.props.selectedMarket}
                  selectedSubselection={this.props.selectedSubselection}
                  markets={this.props.markets}
                  showKickOff={this.props.showKickOff}
                  kickOff={this.handleKickOff}
                  haveLiveMatches={this.props.haveLiveMatches}
                  gameType={this.props.gameType}
                  currentPage={this.props.currentPage}
                  closeModal={this.props.closeModal}
                  changePage={this.props.changePage}
                  activeModal={this.props.activeModal}
                  openModal={this.props.openModal}
                  placedSelections={this.props.placedSelections[this.props.roundId]}
                  placedSelectionsTurbo={this.props.placedSelectionsTurbo[this.props.roundId]}
                  roundId={this.props.roundId}
                  fetchStatistics={this.props.fetchStatistics}
                  statistics={this.props.statistics}
                />
              )}
            {this.props.currentPage === Constants.PAGES.BETSLIP && (
              <Betslip
                kickOff={this.handleKickOff}
                haveLiveMatches={this.props.haveLiveMatches}
              />
            )}
          </>
        )
    );
  }
}
export default connect(
  mapToProps,
  actionsToProps,
)(Bets);