All files / src/pages/AcquirerPortal/LegalDocuments/LegalDocumentDetail/components HistoryListItem.tsx

100% Statements 11/11
73.33% Branches 11/15
100% Functions 5/5
100% Lines 9/9

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 118 119 120 121 122 123 124                                                      38x   38x       38x       38x                                                                                                                         6x 82x 38x                   19x             42x            
import { Box, Stack } from "@mui/material";
import { BellIcon, CheckIcon } from "@phosphor-icons/react";
import GiveText from "@shared/Text/GiveText";
import GiveAvatar from "@shared/Avatar/GiveAvatar";
import { DotComponent } from "@shared/atoms";
import { styled, useAppTheme } from "@theme/v2/Provider";
import { formatPublishedDate } from "../../publishedDate";
import type { VersionHistoryItem } from "../../types";
 
interface HistoryListItemProps {
  item: VersionHistoryItem;
  /** The most recent (currently published) version — shown with a check. */
  isCurrent?: boolean;
  /** The version currently being viewed — row is highlighted. */
  isActive?: boolean;
  /** Hide the connecting line under the last item in the timeline. */
  showConnector?: boolean;
  onSelect: () => void;
}
 
export default function HistoryListItem({
  item,
  isCurrent = false,
  isActive = false,
  showConnector = true,
  onSelect,
}: HistoryListItemProps) {
  const { palette } = useAppTheme();
 
  const { version, publishedBy, publishedDate, notifiedDate } = item;
  // published_at is a calendar date (midnight UTC) — format in UTC or it
  // renders as the previous day; a time-of-day would always be a meaningless
  // 00:00, so only the date is shown. See publishedDate.ts.
  const formattedDate = publishedDate
    ? formatPublishedDate(publishedDate)
    : "—";
 
  return (
    <Stack
      role="button"
      tabIndex={0}
      onClick={onSelect}
      direction="row"
      gap="16px"
      padding="16px 20px 8px 20px"
      bgcolor={
        isActive ? palette.surface?.["secondary-transparent"] : undefined
      }
      sx={{
        cursor: "pointer",
        "&:hover": { backgroundColor: palette.surface?.secondary },
      }}
    >
      <Stack direction="column" alignItems="center">
        <IconContainer success={isCurrent}>
          {isCurrent ? (
            <CheckIcon size={16} color={palette["text-inverted"]?.primary} />
          ) : (
            <DotComponent
              size="8px"
              bgColor={palette.icon?.["icon-secondary"]}
            />
          )}
        </IconContainer>
        {showConnector && <VerticalLine />}
      </Stack>
 
      <Stack direction="column" gap="8px">
        <GiveText variant="bodyM" color="primary">
          Version {version}
        </GiveText>
        <GiveText variant="bodyS" color="secondary">
          {formattedDate}
        </GiveText>
        <RowContainer>
          <GiveAvatar
            imageUrl={publishedBy?.imageURL}
            name={publishedBy?.name}
            size="16px"
            shape="rounded"
          />
          <GiveText variant="bodyS" color="secondary">
            {publishedBy?.name}
          </GiveText>
        </RowContainer>
        {!!notifiedDate && (
          <RowContainer>
            <BellIcon size={16} color={palette.icon?.["icon-secondary"]} />
            <GiveText variant="bodyS" color="secondary">
              Merchants notified
            </GiveText>
          </RowContainer>
        )}
      </Stack>
    </Stack>
  );
}
 
const IconContainer = styled(Box, {
  shouldForwardProp: (prop) => prop !== "success",
})<{ success?: boolean }>(({ theme, success }) => ({
  display: "flex",
  alignItems: "center",
  justifyContent: "center",
  width: "24px",
  height: "24px",
  borderRadius: "50px",
  backgroundColor: success ? theme.palette.primitive?.success[50] : undefined,
}));
 
const VerticalLine = styled(Box)(({ theme }) => ({
  width: "1px",
  height: "32px",
  background: theme?.palette?.icon?.["icon-secondary"],
  marginTop: "16px",
}));
 
const RowContainer = styled(Stack)(() => ({
  display: "flex",
  flexDirection: "row",
  alignItems: "center",
  gap: "8px",
}));