All files / app/components MapAnimation.tsx

86.36% Statements 19/22
0% Branches 0/3
80% Functions 4/5
85% Lines 17/20

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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 1181x 1x 1x 1x 1x 1x 1x   1x   2x                           2x                     3x 2x 2x 2x   2x 1x                                       2x                                                                                                                
import { Box, Skeleton, styled, Typography } from "@mui/material";
import { useTranslation } from "i18n";
import { LANDING } from "i18n/namespaces";
import Lottie from "lottie-react";
import Sentry from "platform/sentry";
import { useEffect, useState } from "react";
import { theme } from "theme";
 
import Alert from "./Alert";
 
const AnimationContainer = styled("div")(({ theme }) => ({
  width: "595px",
  height: "524px",
  display: "flex",
  justifyContent: "center",
  alignItems: "center",
 
  [theme.breakpoints.down("md")]: {
    width: "100%",
    height: "auto",
    minHeight: "300px",
  },
}));
 
const Attribution = styled(Typography)(({ theme }) => ({
  position: "absolute",
  bottom: 8,
  right: 10,
  background: "rgba(255,255,255,0.8)",
  padding: "2px 8px",
  borderRadius: 4,
  pointerEvents: "none",
  zIndex: 2,
}));
 
export default function MapAnimation() {
  const { t } = useTranslation([LANDING]);
  const [animationData, setAnimationData] = useState(null);
  const [error, setError] = useState<Error | null>(null);
 
  useEffect(() => {
    fetch("https://cdn.couchers.org/img/hero/hero-animation.json")
      .then((res) => {
        Iif (!res.ok) {
          Sentry.captureException(
            `Failed to load map animation: ${res.statusText}`,
            {
              tags: {
                component: "auth/useAuthStore",
                action: "logout",
                status: res.status,
              },
            },
          );
        }
        return res.json();
      })
      .then(setAnimationData)
      .catch(setError);
  }, []);
 
  Iif (error) {
    return (
      <Alert severity="error" sx={{ width: "100%" }}>
        {t("landing:animation_error")}
      </Alert>
    );
  }
 
  return (
    <AnimationContainer>
      {animationData ? (
        <Box
          sx={{
            position: "relative",
            width: 595,
            height: 524,
            [theme.breakpoints.down("md")]: {
              width: "100%",
              height: "auto",
              minHeight: "300px",
              marginTop: theme.spacing(4),
            },
          }}
        >
          <Lottie animationData={animationData} loop={true} />
          <Attribution variant="caption">Map data © 2025 Google</Attribution>
        </Box>
      ) : (
        <Box
          sx={{
            position: "relative",
            height: 524,
            width: 595,
            [theme.breakpoints.down("md")]: {
              width: "100%",
              height: "auto",
              minHeight: "300px",
              marginTop: theme.spacing(4),
            },
          }}
        >
          <Skeleton
            variant="rectangular"
            sx={{
              width: 595,
              height: 524,
              borderRadius: "10px",
              flexShrink: 0,
            }}
          />
          <Attribution variant="caption">Map data © 2025 Google</Attribution>
        </Box>
      )}
    </AnimationContainer>
  );
}