All files / src/components/Merchants/MerchantPreview/modals/shared GiveDetailsMatchList.tsx

72% Statements 18/25
57.69% Branches 15/26
87.5% Functions 7/8
81.81% Lines 18/22

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 125 126 127                                          1x   1x 3x 3x                   3x     3x     1x 2x   2x   2x                                                                               1x 8x   1x         8x   8x     8x 22x                       14x                            
import { Stack } from "@mui/material";
import { ArrowSquareOutIcon } from "@phosphor-icons/react";
 
import GiveText from "@shared/Text/GiveText";
import GiveLink from "@shared/Link/GiveLink";
import GiveCollapsableComponent from "@features/Merchants/MerchantSidePanel/GiveMerchantFile/businessOwners/GiveCollapsableComponent";
 
import { useAppTheme } from "@theme/v2/Provider";
import { isUrl } from "@sections/PayBuilder/helpers";
 
export interface MatchItem {
  label: string;
  value: any;
}
 
type GiveDetailsMatchListProps = {
  items: MatchItem[][];
  testIdPrefix?: string;
  useLabelAsTitle?: boolean;
};
 
const EMPTY_VALUE = "None";
 
const formatValue = (value: MatchItem["value"]): string => {
  Iif (value == null || value === "") return EMPTY_VALUE;
  Iif (Array.isArray(value)) {
    if (value.length === 0) return EMPTY_VALUE;
    return value
      .map((item) =>
        typeof item === "object"
          ? Object.values(item).filter(Boolean).join(", ")
          : String(item),
      )
      .join(" ");
  }
  Iif (typeof value === "object") {
    return Object.values(value).filter(Boolean).join(", ");
  }
  return String(value);
};
 
const MatchRow = ({ item, isEven }: { item: MatchItem; isEven: boolean }) => {
  const { palette } = useAppTheme();
 
  const valueIsUrl = typeof item.value === "string" && isUrl(item.value);
 
  return (
    <Stack
      direction="row"
      alignItems="flex-start"
      sx={{
        backgroundColor: isEven ? palette.surface?.secondary : "transparent",
        padding: "12px 16px",
      }}
    >
      <GiveText
        variant="bodyS"
        color="secondary"
        sx={{ width: "50%", wordBreak: "break-all" }}
      >
        {item.label}
      </GiveText>
 
      {valueIsUrl ? (
        <GiveLink
          href={item.value as string}
          openInNewTab
          Icon={ArrowSquareOutIcon}
          iconPosition="right"
          sx={{
            width: "50%",
            color: palette.primitive?.blue?.[100],
            wordBreak: "break-all",
          }}
        >
          Open
        </GiveLink>
      ) : (
        <GiveText variant="bodyS" sx={{ width: "50%", wordBreak: "break-all" }}>
          {formatValue(item.value)}
        </GiveText>
      )}
    </Stack>
  );
};
 
const getGroupTitle = (group: MatchItem[], useLabelAsTitle: boolean) =>
  useLabelAsTitle ? group[0]?.label ?? "Details" : formatValue(group[0]?.value);
 
const GiveDetailsMatchList = ({
  items,
  testIdPrefix = "details",
  useLabelAsTitle = true,
}: GiveDetailsMatchListProps) => {
  Iif (!items.length) return null;
 
  return (
    <Stack gap={0}>
      {items.map((group, groupIdx) => (
        <GiveCollapsableComponent
          key={`${groupIdx}-${group.map((i) => i.label).join("-")}`}
          title={
            <GiveText variant="bodyS">
              {getGroupTitle(group, useLabelAsTitle)}
            </GiveText>
          }
          isFirst={groupIdx === 0}
          isLast={groupIdx === items.length - 1}
          testId={`${testIdPrefix}-item-${groupIdx}`}
        >
          <Stack pb={2}>
            {group.slice(1).map((item, itemIdx) => (
              <MatchRow
                key={`${item.label}-${itemIdx}`}
                item={item}
                isEven={itemIdx % 2 === 0}
              />
            ))}
          </Stack>
        </GiveCollapsableComponent>
      ))}
    </Stack>
  );
};
 
export default GiveDetailsMatchList;