FileUploadPopover.tsx 1.75 KB
import React, { useCallback, useRef } from "react";
import Dragger from "antd/lib/upload/Dragger";
import { InboxOutlined } from "@ant-design/icons";
import { useApi } from "util/useApi";

export type FileUploadPopoverProps = {
  root: number;
  reload: () => void;
};

export function FileUploadPopover({ root, reload }: FileUploadPopoverProps) {
  const api = useApi();
  const fields = useRef<any>();
  const stateMap = useRef<Record<string, number>>({});

  const getS3Object = useCallback(
    async (file: File) => {
      const body = new URLSearchParams();
      body.set("name", file.name);
      body.set("size", file.size.toString());

      const response = await api
        .post(`/items/${root}/upload/`, { body })
        .json<any>();

      stateMap.current[file.name] = response.item.id;
      fields.current = response.signed_url.fields;
      return response.signed_url.url;
    },
    [api, root]
  );

  const setObjectStatus = useCallback(
    async (info) => {
      if (info.file.status === "done") {
        const id = stateMap.current[info.file.name];
        if (typeof id !== "undefined") {
          const body = new URLSearchParams();
          body.set("item_id", id.toString());
          await api.post(`/items/${id}/status/`, { body });
          reload();
        }
      }
    },
    [api, reload]
  );

  return (
    <Dragger
      name="file"
      multiple={true}
      action={getS3Object}
      data={() => fields.current}
      onChange={setObjectStatus}
      style={{ padding: 40 }}
    >
      <p className="ant-upload-drag-icon">
        <InboxOutlined />
      </p>
      <p className="ant-upload-text">
        업로드할 파일을 선택하거나 드래그 하세요
      </p>
      <p className="ant-upload-hint"></p>
    </Dragger>
  );
}