All files / src/sections/PayBuilder/Forms/About ImageUploader.tsx

82.35% Statements 14/17
80% Branches 8/10
71.42% Functions 5/7
86.66% Lines 13/15

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                                                    5x 5x     5x           5x   5x   5x               5x                 2x 2x       1x 1x           5x                                               5x                        
import { Stack } from "@mui/material";
import { PlusIcon } from "@phosphor-icons/react";
import { styled, useAppTheme } from "@theme/v2/Provider";
import Dropzone, {
  IFileWithMeta,
  ILayoutProps,
  StatusValue,
} from "react-dropzone-uploader";
import { useAccessControl } from "features/Permissions/AccessControl";
import RESOURCE_BASE, { OPERATIONS } from "@constants/permissions";
import {
  ACCEPTED_IMAGE_FORMATS,
  ACCEPTED_IMAGE_PNG_FORMATS,
} from "@constants/constants";
import { useRef } from "react";
import { showMessage } from "@common/Toast";
 
function ImageUploader({
  filterPNGOnly,
  setImageToEdit,
  isUploading,
}: {
  filterPNGOnly?: boolean;
  setImageToEdit: (e: any) => void;
  isUploading?: boolean;
}) {
  const ref = useRef<HTMLInputElement>(null);
  const { palette } = useAppTheme();
 
  // Access Control
  const isAddImageAllowed = useAccessControl({
    resource: RESOURCE_BASE.MEDIA_ITEM,
    operation: OPERATIONS.CREATE,
    withPortal: true,
  });
 
  const disabledAddImage = isUploading || !isAddImageAllowed;
 
  const openFilePicker = () => ref.current?.click();
 
  return (
    <Dropzone
      onChangeStatus={(metaFile: IFileWithMeta, status: StatusValue) => {
        if (status === "done")
          setImageToEdit({ imageToEdit: metaFile.file, id: undefined });
      }}
      disabled={disabledAddImage}
      InputComponent={() => (
        <input
          multiple
          type="file"
          accept={
            filterPNGOnly ? ACCEPTED_IMAGE_PNG_FORMATS : ACCEPTED_IMAGE_FORMATS
          }
          ref={ref}
          disabled={!isAddImageAllowed}
          onChange={(e) => {
            const uploadedFile = e.target.files?.[0];
            if (
              filterPNGOnly &&
              uploadedFile?.type !== ACCEPTED_IMAGE_PNG_FORMATS
            )
              showMessage("Error", "only png files allowed");
            else setImageToEdit({ imageToEdit: uploadedFile, id: undefined });
          }}
          hidden
        />
      )}
      LayoutComponent={({ input }: ILayoutProps) => (
        <>
          <ActionButton onClick={openFilePicker}>
            <Stack
              height="48px"
              width="48px"
              borderRadius="50%"
              p="12px"
              justifyContent="center"
              alignItems="center"
              bgcolor={palette.primitive?.transparent["darken-5"]}
            >
              <PlusIcon size="24px" />
            </Stack>
          </ActionButton>
          {input}
        </>
      )}
    />
  );
}
 
export default ImageUploader;
 
// Styled Components
const ActionButton = styled(Stack)(({ theme }) => ({
  width: "114px",
  height: "114px",
  cursor: "pointer",
  backgroundColor: theme.palette.primitive?.transparent["darken-5"],
  alignItems: "center",
  justifyContent: "center",
  borderRadius: "8px",
  [theme.breakpoints.down("sm")]: {
    width: "calc(50% - 16px)",
  },
}));