containers/Settings/StatsTemplateFile/StatsTemplatesFile.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import {
  aGetPermissions,
  aGetStatsDownloadTemplatesFile,
  aGetStatsTemplatesFiles,
  aGetStatsUploadTemplatesFile,
} from '../../../reducers/actions';
import { STATS_TEMPLATES_FILES_TXT, PERMISSIONS } from '../../../constants';
import { getStatsTemplatesFiles, getDownloadedOddsTemplatesFile } from '../../../selectors/settings';
import { checkPermisson, isFetched, isLastRecord, hasRecord, getSelectedTimezone } from '../../../selectors/common';
import { getCountryDateTime } from '../../../utils/common';
import ScrollTable from '../../../components/ScrollTable';
import TableNoResult from '../../../components/TableNoResult';
import StatsTemplateFileRow from './StatsTemplatesFilesRow';

const mapToProps = (state) => ({
  statsTemplatesFiles: getStatsTemplatesFiles(state),
  downloadedFile: getDownloadedOddsTemplatesFile(state),
  checkPermisson: (payload) => checkPermisson(state, payload),
  isFetched: isFetched(state),
  isLastRecord: isLastRecord(state),
  hasRecord: hasRecord(state),
  selectedTimezone: getSelectedTimezone(state),
});

const actionsToProps = (dispatch) => ({
  getStatsTemplateFiles: (payload) => dispatch(aGetStatsTemplatesFiles(payload)),
  getDownloadStatsTemplatesFile: (payload) => dispatch(aGetStatsDownloadTemplatesFile(payload)),
  getUploadStatsTemplateFile: (payload) => dispatch(aGetStatsUploadTemplatesFile(payload)),
  getPermissions: (payload) => dispatch(aGetPermissions(payload)),
});

/**
 * @class
 * @property {object} props
 * @property {Array} props.statsTemplatesFiles stats Templates files data
 * @property {boolean} props.checkPermisson
 * @property {Function} props.getStatsTemplateFiles Call API for stats templates files
 * @property {Function} props.getUploadStatsTemplateFile Call API to upload template file
 * @property {Function} props.getDownloadStatsTemplatesFile Call API to download template file
 *
 */
class StatsTemplatesFile extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputLabel: STATS_TEMPLATES_FILES_TXT.inputLabel,
      isError: false,
    };
    /**
     * @member {object}
     * @description Check of user have permission for some of actions
     * @property {boolean} view
     * @property {boolean} upload
     * @property {boolean} download
     */
    this.hasPermissionTo = {
      view: props.checkPermisson(PERMISSIONS.STATS_TEMPLATE_FILES_VIEW),
      upload: props.checkPermisson(PERMISSIONS.STATS_TEMPLATE_FILES_UPLOAD),
      download: props.checkPermisson(PERMISSIONS.STATS_TEMPLATE_FILES_DOWNLOAD),
    };
  }

  /**
   * Get initial data
   *
   * @returns {void}
   */
  componentDidMount() {
    this.refreshTable();
  }

  /**
   * on component update download document
   *
   * @param {object} prevProps
   * @returns {void}
   */
  componentDidUpdate(prevProps) {
    if (prevProps.downloadedFile !== this.props.downloadedFile) {
      window.location.assign(this.props.downloadedFile.url);
    }
  }

  /**
   * Refresh and update stats templates files table
   *
   * @function
   * @returns {void}
   */
  refreshTable = () => {
    this.props.getStatsTemplateFiles();
  };

  /**
   * Upload stats template file
   *
   * @function
   * @returns {void}
   */
  uploadStatsTemplateFile = () => {
    this.props.getUploadStatsTemplateFile(this.fileUpload.files[0]);
    this.fileUpload.value = '';
    this.setState({ inputLabel: STATS_TEMPLATES_FILES_TXT.inputLabel });
  };

  /**
   * download stats templates file
   *
   * @function
   * @param {object} file
   * @returns {void}
   */
  downloadFile = (file) => {
    this.props.getDownloadStatsTemplatesFile(file);
  };

  /**
   * put correct label after change input
   *
   * @function
   * @returns {void}
   */
  onChangeInputFile = () => {
    const newTxt =
      this.fileUpload && this.fileUpload.files.length > 0
        ? `${`${this.fileUpload.files[0].name}`}`
        : STATS_TEMPLATES_FILES_TXT.inputLabel;
    const extention = newTxt.substring(newTxt.lastIndexOf('.') + 1, newTxt.length);
    if (extention === STATS_TEMPLATES_FILES_TXT.validExtention) {
      this.setState({
        inputLabel: newTxt,
        isError: false,
      });
    } else {
      this.setState({
        inputLabel: STATS_TEMPLATES_FILES_TXT.inputLabel,
        isError: true,
      });
    }
  };

  /**
   * Render
   *
   * @returns {view}
   */
  render() {
    return (
      this.hasPermissionTo.view && (
        <div className="user">
          <ScrollTable
            loadMore={this.refreshTable}
            isFetched={this.props.isFetched}
            isLastRecord={this.props.isLastRecord}
          >
            <>
              <table className="table-style table-s">
                <thead>
                  <tr>
                    <th>Name</th>
                    <th>Date</th>
                    <th>User</th>
                    <th>Download</th>
                  </tr>
                </thead>
                <tbody>
                  <StatsTemplateFileRow
                    statsTemplatesFiles={this.props.statsTemplatesFiles}
                    getCountryDateTime={getCountryDateTime}
                    selectedTimezone={this.props.selectedTimezone}
                    hasPermissionTo={this.hasPermissionTo}
                    downloadFile={this.downloadFile}
                  />
                </tbody>
              </table>
              {!this.props.hasRecord && !this.props.statsTemplatesFiles.length && <TableNoResult />}
            </>
          </ScrollTable>
          <div className="user__settings mt-20">
            <div className="row">
              {this.hasPermissionTo.upload && (
                <div className="col-sm-12 d-flex align-items-center">
                  <p className="m-0">Upload new file (*File accepted: xlsx)</p>
                  <div className="ml-30">
                    <input
                      type="file"
                      className="d-none"
                      id="file"
                      name="file"
                      ref={(ref) => {
                        this.fileUpload = ref;
                      }}
                      onChange={this.onChangeInputFile}
                    />
                    <label htmlFor="file" className="m-0">
                      <div className="file-btn">{this.state.inputLabel}</div>
                    </label>
                  </div>
                  <button
                    id="statsTemplatesFile_UploadBtn"
                    className="btn btn-primary ml-30"
                    onClick={this.uploadStatsTemplateFile}
                    type="button"
                    disabled={(this.fileUpload && this.fileUpload.files.length < 1) || this.state.isError === true}
                  >
                    Upload
                  </button>
                </div>
              )}
            </div>
            {this.state.isError && <div className="error-txt mt-2">{STATS_TEMPLATES_FILES_TXT.inputErrorMgs}</div>}
          </div>
          <div className="user__info mt-20">*Uploaded files will be displayed in the table(s) above</div>
        </div>
      )
    );
  }
}

export default connect(mapToProps, actionsToProps)(StatsTemplatesFile);