containers/App/index.js

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

import { Outlet } from 'react-router-dom';
import { onMessage, getMessaging } from 'firebase/messaging';
import { getIsLoading, getCnt, getSelectedTimezone, getFilterData } from '../../selectors/common';
import SVGProvider from '../../components/SVG/SVGProvider';
import Loader from '../../components/Loader';
import {
  PAGES,
  LOCAL_STORAGE_KEYS,
  COUNTRY_TIMEZONES,
  COUPONS_TYPE,
  NOTIFICATIONS,
  COUNTRY_TIMEZONE_ID,
} from '../../constants';
import NotificationPrompt from '../../firebase/NotificationPrompt';
import { aSaveToken, aSetSelectedTimezone } from '../../reducers/common';
import { aGetInit, aUpdateSettledCoupons } from '../../reducers/actions';
import { withRouterHooks } from '../../utils/router';
import { aLocationChange } from '../../reducers/bonus';

const mapToProps = (state) => ({
  isLoading: getIsLoading(state),
  cnt: getCnt(state),
  selectedTimezone: getSelectedTimezone(state),
  filters: getFilterData(state),
});

const actionsToProps = (dispatch) => ({
  checkSession: (payload) => dispatch(aGetInit(payload)),
  setSelectedTimeZone: (payload) => dispatch(aSetSelectedTimezone(payload)),
  saveToken: (payload) => dispatch(aSaveToken(payload)),
  updateSettledCoupons: (payload) => dispatch(aUpdateSettledCoupons(payload)),
  changeLocation: (payload) => dispatch(aLocationChange(payload)),
});

/**
 * @class
 * @property {object} props
 * @property {string} props.cnt Indicate CNT path
 * @property {boolean} props.isLoading Indicate is loader showen
 * @property {Function} props.checkSession Check session API call
 */
class App extends Component {
  /**
   * Call check session API
   *
   * @returns {void}
   */
  componentDidMount() {
    const selectedTimezoneId =
      parseInt(localStorage.getItem(LOCAL_STORAGE_KEYS.SELECTED_TIMEZONE)) ||
      COUNTRY_TIMEZONE_ID[process.env.BUNDLE_SKIN];
    this.props.checkSession({ navigate: this.props.navigate, location: this.props.location });
    if (selectedTimezoneId) {
      this.props.setSelectedTimeZone(COUNTRY_TIMEZONES.find((timezone) => timezone.id === selectedTimezoneId));
    }

    this.triggerFirebaseMessageListener();
  }

  componentDidUpdate(prevProps) {
    if (prevProps.selectedTimezone.id !== this.props.selectedTimezone.id) {
      this.setState({});
    }
    if (prevProps.location.pathname !== this.props.location.pathname) {
      this.props.changeLocation({ pathname: this.props.location.pathname });
    }
  }

  getUpdatedSettledCoupons(notificationObject) {
    const couponId = notificationObject?.data?.reference;

    const filters = {};
    filters['filter.couponId'] = couponId;

    this.props.updateSettledCoupons({ ...filters, type: COUPONS_TYPE.SETTLED });
  }

  triggerFirebaseMessageListener() {
    const messaging = getMessaging();

    onMessage(messaging, (payload) => {
      if (
        this.props.location.pathname === PAGES.COUPONS_SETTLED_VIEW &&
        payload?.data?.type === NOTIFICATIONS.TYPES.VOID_COUPON &&
        payload?.data?.status === NOTIFICATIONS.STATUS.COMPLETED
      ) {
        this.getUpdatedSettledCoupons(payload);
      }
    });
  }

  /**
   * Render
   *
   * @returns {view}
   */
  render() {
    return (
      <SVGProvider cnt={this.props.cnt}>
        <NotificationPrompt saveToken={this.props.saveToken} />

        {this.props.isLoading === true ? <Loader /> : <Outlet />}
      </SVGProvider>
    );
  }
}

export default connect(mapToProps, actionsToProps)(withRouterHooks(App));