Skip to content
Snippets Groups Projects
FileField.tsx 2.41 KiB
Newer Older
import { Box, Button, ButtonGroup, Tooltip } from "@mui/material";
import FileUploadIcon from "@mui/icons-material/FileUpload";
import Visibility from "@mui/icons-material/Visibility";
import { ChangeEventHandler, useRef } from "react";
import { CWFile } from "@/types";

interface FileFieldProps {
  label: string;
  value?: CWFile;
  disabled?: boolean;
  onChange?: (file: CWFile) => void;
}

export function FileField({
  label,
  value,
  disabled = false,
  onChange,
}: FileFieldProps) {
  const ref = useRef<HTMLInputElement>(null);

  const onPressOpen = async () => {
    let fileToOpen = value?.data;
    // The file is available on the server, fetch it
    if (!fileToOpen && value?.downloadUrl) {
      const response = await fetch(value.downloadUrl, {
        credentials: "include",
      });
      fileToOpen = await response.blob();
    }
    if (fileToOpen) {
      const url = URL.createObjectURL(fileToOpen);
      window.open(url);
    } else {
      console.warn("No file available either locally or on the server");
    }
  };

  const chooseFile = () => {
    ref.current?.click();
  };

  const onFileChange: ChangeEventHandler<HTMLInputElement> = (e) => {
    if (e.target.files && e.target.files.length > 0 && onChange) {
      const file = e.target.files[0];
      if (value) {
        onChange({
          ...value,
          data: file,
        });
      } else {
        onChange({
          data: file,
        });
      }
    }
  };

  const filePresent = value?.downloadUrl || value?.data;

  return (
    <>
      <input
        type="file"
        style={{ display: "none" }}
        ref={ref}
        onChange={onFileChange}
      />
      <ButtonGroup variant={filePresent ? "outlined" : "text"}>
        <Button
          fullWidth
          startIcon={<FileUploadIcon />}
          disabled={disabled}
          onClick={chooseFile}
        >
          {label}: {filePresent ? "Modifier le fichier" : "Choisir un fichier"}
        </Button>
        <Tooltip
          title={
            filePresent ? "Télécharger le fichier" : "Aucun fichier en ligne"
          }
        >
          {/* This box is necessary for the tooltip to show */}
          <Box>
            <Button
              startIcon={<Visibility />}
              disabled={disabled || !filePresent}
              onClick={onPressOpen}
            >
              Voir
            </Button>
          </Box>
        </Tooltip>
      </ButtonGroup>
    </>
  );
}