All files / app/features/donations DonationBanner.tsx

100% Statements 31/31
100% Branches 7/7
100% Functions 5/5
100% Lines 29/29

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 981x 1x 1x 1x 1x 1x 1x 1x 1x   1x   1x   7x                         13x 29x 29x     29x     29x     29x   29x 17x 13x         4x       29x 4x 4x     29x 1x 1x     29x                                                                        
import VolunteerActivismIcon from "@mui/icons-material/VolunteerActivism";
import { Alert, alpha, Button, styled } from "@mui/material";
import { useTranslation } from "i18n";
import { GLOBAL } from "i18n/namespaces";
import { useRouter } from "next/router";
import { usePersistedState } from "platform/usePersistedState";
import React, { useEffect, useState } from "react";
import { donationsRoute } from "routes";
import { theme } from "theme";
 
import useAccountInfo from "../auth/useAccountInfo";
 
const TIME_BETWEEN_NAGS_MS = 24 * 60 * 60 * 1000; // 24 hours
 
const Wrapper = styled("div")(({ theme }) => ({
  display: "flex",
  justifyContent: "space-between",
  alignItems: "center",
  width: "100%",
  gap: theme.spacing(2),
  [theme.breakpoints.down("md")]: {
    flexDirection: "column",
    alignItems: "center",
    gap: theme.spacing(1),
  },
}));
 
export function DonationBanner() {
  const { t } = useTranslation(GLOBAL);
  const router = useRouter();
 
  // the epoch value of the last time this banner was dismissed
  const [lastDismissedEpoch, setLastDismissedEpoch] = usePersistedState<
    number | null
  >("donation_banner.dismissed", null);
  const [bannerVisible, setBannerVisible] = useState<boolean>(false);
 
  const { data: accountInfo, isLoading: isAccountInfoLoading } =
    useAccountInfo();
 
  useEffect(() => {
    if (!isAccountInfoLoading && accountInfo?.shouldShowDonationBanner) {
      setBannerVisible(
        !lastDismissedEpoch ||
          new Date().getTime() - lastDismissedEpoch > TIME_BETWEEN_NAGS_MS,
      );
    } else {
      setBannerVisible(false);
    }
  }, [isAccountInfoLoading, accountInfo, lastDismissedEpoch]);
 
  const handleClose = () => {
    setLastDismissedEpoch(new Date().getTime());
    setBannerVisible(false);
  };
 
  const handleDonateClick = () => {
    router.push(`${donationsRoute}?utm_source=donation_banner`);
    setBannerVisible(false);
  };
 
  if (!bannerVisible) return null;
 
  return (
    <Alert
      icon={<VolunteerActivismIcon />}
      onClose={handleClose}
      sx={{
        alignItems: "center",
        ".MuiAlert-message": { width: "100%" },
        backgroundColor: alpha(theme.palette.secondary.main, 0.08),
        color: theme.palette.text.primary,
        "& .MuiAlert-icon": {
          color: theme.palette.secondary.main,
        },
      }}
    >
      <Wrapper>
        <span>{t("donation_banner.message")}</span>
        <Button
          variant="contained"
          size="small"
          sx={{
            backgroundColor: theme.palette.secondary.main,
            flexShrink: 0,
            "&:hover": {
              backgroundColor: theme.palette.secondary.dark,
            },
          }}
          onClick={handleDonateClick}
        >
          {t("donation_banner.button")}
        </Button>
      </Wrapper>
    </Alert>
  );
}