All files / app/features/celebration100k Celebration100k.tsx

100% Statements 27/27
100% Branches 17/17
100% Functions 4/4
100% Lines 25/25

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 511x 1x 1x 1x 1x   1x 1x 1x 1x                     11x 32x 32x 32x   32x 32x 32x     32x 32x   32x   22x   3x 3x     32x       1x 1x        
import { useFeatureValue } from "@growthbook/growthbook-react";
import { useAuthContext } from "features/auth/AuthProvider";
import { usePersistedState } from "platform/usePersistedState";
import { useEffect, useState } from "react";
import { useIsClient } from "utils/hooks";
 
import CelebrationBanner from "./CelebrationBanner";
import CelebrationOverlay from "./CelebrationOverlay";
import { CELEBRATION_100K_FLAG, CELEBRATION_100K_SEEN_KEY } from "./constants";
import { useMemberClusters } from "./useMemberClusters";
 
interface Celebration100kProps {
  /** Play the overlay by itself the first time this device opens the page */
  autoPlay?: boolean;
}
 
/**
 * The 100k members celebration for logged-in members, switched on and off with a feature flag for the week.
 * Shows a one-row banner with a replay, and (when `autoPlay` is set) plays the overlay once per device.
 */
export default function Celebration100k({ autoPlay = false }: Celebration100kProps) {
  const isFlagOn = useFeatureValue(CELEBRATION_100K_FLAG, false);
  const { authState } = useAuthContext();
  const isEnabled = isFlagOn && authState.authenticated;
  // Storage is only readable in the browser, so render nothing until then to avoid a hydration mismatch
  const isClient = useIsClient();
  const [hasSeen, setHasSeen] = usePersistedState(CELEBRATION_100K_SEEN_KEY, false);
  const [isOpen, setIsOpen] = useState(false);
 
  // Load the map data before opening, so slow connections don't sit on an empty map
  const willAutoPlay = isEnabled && isClient && autoPlay && !hasSeen;
  const { isSuccess: membersLoaded } = useMemberClusters(willAutoPlay);
 
  useEffect(() => {
    // If the data doesn't load (slow or dropped connection), it autoplays on a later visit instead
    if (!willAutoPlay || !membersLoaded) return;
    // Marked as seen as soon as it starts, so closing early or reloading doesn't play it again
    setHasSeen(true);
    setIsOpen(true);
  }, [willAutoPlay, membersLoaded, setHasSeen]);
 
  if (!isEnabled || !isClient) return null;
 
  return (
    <>
      {(hasSeen || !autoPlay) && <CelebrationBanner onReplay={() => setIsOpen(true)} />}
      <CelebrationOverlay open={isOpen} onClose={() => setIsOpen(false)} />
    </>
  );
}