All files / app/features/notifications PushNotificationBanner.tsx

0% Statements 0/38
0% Branches 0/9
0% Functions 0/5
0% Lines 0/36

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 98 99 100                                                                                                                                                                                                       
import { Alert, Button, styled } from "@mui/material";
import { useAuthContext } from "features/auth/AuthProvider";
import { useTranslation } from "i18n";
import { NOTIFICATIONS } from "i18n/namespaces";
import { usePersistedState } from "platform/usePersistedState";
import React, { useEffect, useState } from "react";
import { Trans } from "react-i18next";
import { theme } from "theme";
 
import { checkPushEnabled, turnPushNotificationsOn } from "./utils/helpers";
 
const TIME_BETWEEN_NAGS_MS = 180 * 86400 * 1_000; // 180 days
 
const Wrapper = styled("div")({
  display: "flex",
  justifyContent: "space-between",
  alignItems: "center",
  width: "100%",
});
 
export function PushNotificationBanner() {
  const { t } = useTranslation([NOTIFICATIONS]);
  // the epoch value of the last time this banner was dismissed
  const [lastDismissedEpoch, setLastDismissedEpoch] = usePersistedState<
    number | null
  >("notification_banner.dismissed", null);
  const [bannerVisible, setBannerVisible] = useState<boolean>(false);
  const [shouldPromptAllow, setShouldPromptAllow] = useState<boolean>(false);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
 
  const {
    authState: { authenticated },
  } = useAuthContext();
 
  useEffect(() => {
    const checkPush = async () => {
      Iif (!authenticated) return;
      try {
        Iif (!(await checkPushEnabled())) {
          setBannerVisible(
            !lastDismissedEpoch ||
              new Date().getTime() - lastDismissedEpoch > TIME_BETWEEN_NAGS_MS,
          );
        }
      } catch (error) {
        console.error("Error checking for push notification state:", error);
      }
    };
 
    checkPush();
  }, [authenticated, lastDismissedEpoch]);
 
  const dismiss = () => {
    setLastDismissedEpoch(new Date().getTime());
    setBannerVisible(false);
  };
 
  const turnPushNotificationsOnWrap = async () => {
    const result = await turnPushNotificationsOn(setShouldPromptAllow);
    if (!result.success) {
      setErrorMessage(t(result.errorMessage));
    } else {
      setBannerVisible(false);
    }
  };
 
  Iif (!bannerVisible) return null;
 
  Iif (errorMessage) {
    return (
      <Alert severity="error" onClose={dismiss}>
        {errorMessage}
      </Alert>
    );
  }
 
  return shouldPromptAllow ? (
    <Alert severity="info" onClose={dismiss}>
      {t("notification_settings.push_notifications.allow_push")}
    </Alert>
  ) : (
    <Alert
      severity="info"
      onClose={dismiss}
      sx={{ alignItems: "center", ".MuiAlert-message": { width: "100%" } }}
    >
      <Wrapper>
        <Trans i18nKey="global:push_notification_banner.message" />
        <Button
          variant="outlined"
          sx={{ backgroundColor: theme.palette.common.white }}
          onClick={turnPushNotificationsOnWrap}
        >
          {t("global:push_notification_banner.confirm")}
        </Button>
      </Wrapper>
    </Alert>
  );
}