src/components/fragments/BeamImpact/BeamImpactOverview.jsx

import React, {useState, useEffect} from "react";
import {withErrorBoundary} from "components/hocs";
import Fallback from "./Fallback";

/**
 * Component for Beam Impact Overview widget
 *
 * @author Htin Linn Aung
 * @memberof Fragments.Fragments/Beam
 * @param {object} props
 * @param {string} props.widgetColors - From BeamImpact component
 * @param {string} props.widgetId - Provided by Beam. It is in config
 * @param {string} props.patronEmail - From BeamImpact
 * @param {object} props.beam - State in pages/Cart/routes.jsx
 * @param {Function} props.onSeeMoreImpact - Callback for SeeMore button
 * @returns {React.Element} - Component for Beam Impact Overview widget
 */
const BeamImpactOverview = ({
  widgetColors,
  widgetId,
  patronEmail,
  beam,
  onSeeMoreImpact,
}) => {
  const {
    explainerTextColor,
    defaultExplainerTextColor,
    descriptionTextColor,
    impactProgressBarColor,
  } = widgetColors;
  const nonprofit = beam?.widget?.lastNonprofit?.id;
  const explainerColor = explainerTextColor || defaultExplainerTextColor;
  const [beamAppsLoading, setBeamAppsLoading] = useState(false);

  useEffect(() => {
    if (!widgetId) {
      console.error("[Beam Impact] Widget ID is required.");
      return;
    }

    setBeamAppsLoading(true);
    const initializeWidget = async () => {
      // Need to add mechanism to handle duplicate instantiation

      const widget = new window.beamApps.ImpactOverviewWidget({
        containerId: "beam-widget-container",
        forceMobileView: "true",
        loadingScreenContent: "",
        seeMoreButtonCallback: () => onSeeMoreImpact(),
        themeConfig: {
          gradientColors: [descriptionTextColor],
          id: "lunchbox-impact-overview",
          progressBarColors: [
            {
              color: impactProgressBarColor,
              offset: "100%",
            },
          ],
          seeMoreButtonColor: impactProgressBarColor,
          seeMoreButtonTextColor: explainerColor,
          textColor: explainerColor,
        },
        widgetId,
      });
      if (nonprofit) await widget.render(patronEmail, nonprofit);
    };

    if (window.beamApps) {
      setBeamAppsLoading(false);
      initializeWidget();
    }
  }, [beamAppsLoading, window.beamApps]);

  return <div id="beam-widget-container" />;
};

export default withErrorBoundary(BeamImpactOverview, Fallback);