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",
}));
|