All files / src/components/csv ItemCsvButton.tsx

0% Statements 0/94
0% Branches 0/1
0% Functions 0/1
0% Lines 0/94

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 128 129 130 131 132 133 134 135 136 137 138 139 140                                                                                                                                                                                                                                                                                       
import { FC, useState } from 'react';
import { ErrorResponse } from '../../models/errorResponse';
import { useDownloadCsv } from '../../hooks/useDownloadCsv';
import { ItemCsvResponse } from '../../models/itemCsvResponse';
import { useFetchItemCsv } from '../../hooks/useFetchItemCsv';
import { useItemCsvConverter } from '../../hooks/useItemCsvConverter';
import { ItemCsvList } from '../../models/itemCsv';
import { Pending } from '../../models/pending';
import { Loading } from '..';
import CsvResult from './CsvResult';
import ReactModal from 'react-modal';
import { SlCloudDownload } from 'react-icons/sl';
import styled from 'styled-components';
import { TfiClose } from 'react-icons/tfi';
 
const header = [
  { header: '型番', key: 'product_number' },
  { header: '物品名', key: 'name' },
  { header: '個数', key: 'quantity' },
  { header: '物品詳細', key: 'description' },
  //TODO: 保管場所の変更を忘れない
  { header: '保管場所', key: 'place' },
  { header: '使用用途', key: 'usage' },
  { header: '使用時期', key: 'duration' },
  { header: '年間必要数', key: 'required_quantity' },
  { header: '備考', key: 'note' },
];
 
const StyledButton = styled.button`
  height: 70px;
  width: 70px;
  border-radius: 50%;
  background-color: #f6f6f6;
  border: #b3b3b3 1px solid;
  cursor: pointer;
`;
 
const StyledLabel = styled.p`
  font-size: 1.6rem;
`;
 
const StyledBox = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
`;
 
const StyledCloseButton = styled.button`
  height: 30px;
  width: 30px;
  padding: 0;
  margin: 0;
  background-color: rgba(0, 0, 0, 0);
  border: none;
  cursor: pointer;
`;
 
const StyledCloseButtonWrapper = styled.div`
  display: flex;
  justify-content: flex-end;
  width: 100%
`;
 
const ItemCsvButton: FC = () => {
  // set result
  const [result, setResult] = useState<ItemCsvResponse | ErrorResponse | Pending | null>(null);
  // set modal state
  const [modalIsOpen, setIsOpen] = useState<boolean>(true);
  // handle modal close
  const handleClose = (): void => {
    setIsOpen(false);
  };
  // generate and donload csv
  const handlerClick = async (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
    e.preventDefault();
    setIsOpen(true);
    setResult('pending');
    const result: ItemCsvResponse | ErrorResponse = await useFetchItemCsv();
    if ('code' in result && 'message' in result) {
      // Error
      setResult(result);
    } else {
      // Ok
      const body: ItemCsvList = useItemCsvConverter(result);
      await useDownloadCsv('item_list.csv', '物品リスト', header, body);
      setResult(result);
    }
  };
  return (
    <>
      <StyledBox>
        <StyledButton onClick={(e) => handlerClick(e)}>
          <SlCloudDownload style={{ width: '35px', height: '35px', color: '#000000' }} />
        </StyledButton>
        <StyledLabel>物品リストのcsv</StyledLabel>
      </StyledBox>
      {result === null ? (
        //初期表示
        <></>
      ) : (
        <ReactModal
          isOpen={modalIsOpen}
          contentLabel="ItenCsvModal"
          style={{
            overlay: {
              backgroundColor: 'rgba(0, 0, 0, 0.5)',
            },
            content: {
              top: '50%',
              left: '50%',
              transform: 'translate(-50%, -50%)',
              width: '90%',
              minWidth: '320px',
              maxWidth: '900px',
              overflowY: 'scroll',
            },
          }}
        >
          {result === 'pending' ? (
            // 処理中
            <Loading />
          ) : (
            // fetch結果
            <>
              <StyledCloseButtonWrapper>
                <StyledCloseButton onClick={handleClose}>
                  <TfiClose style={{ width: '30px', height: '30px' }} />
                </StyledCloseButton>
              </StyledCloseButtonWrapper>
              <CsvResult result={result} />
            </>
          )}
        </ReactModal>
      )}
    </>
  );
};
 
export default ItemCsvButton;