src/components/fragments/BeamImpact/BeamImpact.jsx

import React from "react";
import {useScript} from "hooks";
import {withTemplate} from "components/hocs";
import {useTemplate} from "components/providers";
import {constants} from "utils";
import BeamNonProfit from "./BeamNonProfit";
import BeamImpactOverview from "./BeamImpactOverview";
import BeamPersonalImpact from "./BeamPersonalImpact";
import BeamCommunityImpact from "./BeamCommunityImpact";
import Fallback from "./Fallback";

const {BEAM_BASE_URL} = constants;
const URL = `${BEAM_BASE_URL}/static/core/js/widgets.js`;
const Step = {
  COMMUNITY_IMPACT: "community-impact",
  COMPLETE: "complete",
  PERSONAL_IMPACT: "personal-impact",
  POST_CHECKOUT: "post-checkout",
  PRE_CHECKOUT: "pre-checkout",
};

/**
 * Depending on the step, returns an appropriate widget
 *
 * @author Htin Linn Aung
 * @memberof Fragments.Fragments/Beam
 * @param {object} props
 * @param {object} props.style - From theme file & withTemplate HOC
 * @param {string} props.widgetId - Provided by Beam. It is in config
 * @param {string} props.patronEmail - From BeamImpact
 * @param {number} props.cartTotal - From BeamImpact
 * @param {string} props.step - Checkout Step
 * @param {object} props.beam - State in pages/Cart/routes.jsx
 * @param {Function} props.setBeam - Setter method for state in pages/Cart/routes.jsx
 * @param {Function} props.onSeeMoreImpact - callback for onClick on 'See More Impact' in pages/Cart/routes.jsx
 * @param {Function} props.onSkipBeamSelection - Alternate Func to bring the user to Routes.PURCHASE_COMPLETE - from home.jsx
 * @returns {React.Element} Main parent Beam Impact component
 */
const BeamImpact = ({
  style,
  widgetId,
  patronEmail,
  cartTotal,
  step,
  beam,
  setBeam,
  onSeeMoreImpact,
  onSkipBeamSelection,
}) => {
  const {labels} = style;
  const templateContext = useTemplate();
  const {colors} = templateContext.theme;
  const explainerTextColor = colors[labels.primary?.split("_")?.[1]];
  const defaultExplainerTextColor = colors[labels.secondary?.split("_")?.[1]];
  const descriptionTextColor = colors[labels.description?.split("_")?.[1]];
  const impactProgressBarColor = colors[labels.timeSecondary?.split("_")?.[1]];
  const baseWarningTextColor = colors[labels.warning?.split("_")?.[1]];
  const widgetColors = {
    baseWarningTextColor,
    defaultExplainerTextColor,
    descriptionTextColor,
    explainerTextColor,
    impactProgressBarColor,
  };

  const {loaded: scriptLoaded, error: scriptErr} = useScript(URL);
  if (!scriptLoaded) {
    return null;
  }
  if (scriptErr) {
    console.error("Unable to load Beam Impact Widget");
    return null;
  }

  switch (step) {
    case Step.COMPLETE:
      return (
        <BeamImpactOverview
          widgetColors={widgetColors}
          widgetId={widgetId}
          patronEmail={patronEmail}
          beam={beam}
          onSeeMoreImpact={onSeeMoreImpact}
        />
      );
    case Step.PRE_CHECKOUT:
    case Step.POST_CHECKOUT:
      return (
        <BeamNonProfit
          style={style}
          widgetColors={widgetColors}
          widgetId={widgetId}
          patronEmail={patronEmail}
          cartTotal={cartTotal}
          step={step}
          beam={beam}
          setBeam={setBeam}
          onSkipBeamSelection={onSkipBeamSelection}
        />
      );
    case Step.PERSONAL_IMPACT:
      return (
        <BeamPersonalImpact
          widgetColors={widgetColors}
          widgetId={widgetId}
          beam={beam}
        />
      );
    case Step.COMMUNITY_IMPACT:
      return (
        <BeamCommunityImpact widgetColors={widgetColors} widgetId={widgetId} />
      );
    default:
      return <Fallback />;
  }
};

export default withTemplate(BeamImpact, "confirmation");