250 lines
7.3 KiB
JavaScript
250 lines
7.3 KiB
JavaScript
import { Icon, Modal, notification, Upload } from "antd";
|
|
import axios from "axios";
|
|
import React, { useState } from "react";
|
|
import { useMutation } from "react-apollo";
|
|
import { useTranslation } from "react-i18next";
|
|
import Resizer from "react-image-file-resizer";
|
|
import {
|
|
INSERT_NEW_DOCUMENT,
|
|
DELETE_DOCUMENT
|
|
} from "../../graphql/documents.queries";
|
|
import "./jobs-documents.styles.scss";
|
|
import { generateCdnThumb } from "../../utils/DocHelpers";
|
|
|
|
function getBase64(file) {
|
|
return new Promise((resolve, reject) => {
|
|
const reader = new FileReader();
|
|
reader.readAsDataURL(file);
|
|
reader.onload = () => resolve(reader.result);
|
|
reader.onerror = error => reject(error);
|
|
});
|
|
}
|
|
|
|
function JobsDocumentsComponent({ shopId, jobId, loading, data, currentUser }) {
|
|
const { t } = useTranslation();
|
|
const [insertNewDocument] = useMutation(INSERT_NEW_DOCUMENT);
|
|
const [deleteDocument] = useMutation(DELETE_DOCUMENT);
|
|
|
|
const [state, setState] = useState({
|
|
previewVisible: false,
|
|
previewImage: ""
|
|
});
|
|
|
|
const [fileList, setFileList] = useState(
|
|
data.reduce((acc, value) => {
|
|
acc.push({
|
|
uid: value.id,
|
|
url: value.thumb_url,
|
|
name: value.name,
|
|
status: "done",
|
|
full_url: value.url,
|
|
key: value.key
|
|
});
|
|
return acc;
|
|
}, [])
|
|
);
|
|
|
|
const uploadToS3 = (
|
|
fileName,
|
|
fileType,
|
|
file,
|
|
onError,
|
|
onSuccess,
|
|
onProgress
|
|
) => {
|
|
axios
|
|
.post("/sign_s3", {
|
|
fileName,
|
|
fileType
|
|
})
|
|
.then(response => {
|
|
var returnData = response.data.data.returnData;
|
|
var signedRequest = returnData.signedRequest;
|
|
var url = returnData.url;
|
|
setState({ ...state, url: url });
|
|
// Put the fileType in the headers for the upload
|
|
var options = {
|
|
headers: {
|
|
"Content-Type": fileType
|
|
},
|
|
onUploadProgress: e => {
|
|
onProgress({ percent: (e.loaded / e.total) * 100 });
|
|
}
|
|
};
|
|
|
|
axios
|
|
.put(signedRequest, file, options)
|
|
.then(response => {
|
|
console.log("response from axios", response);
|
|
insertNewDocument({
|
|
variables: {
|
|
docInput: [
|
|
{
|
|
jobid: jobId,
|
|
uploaded_by: currentUser.email,
|
|
url,
|
|
thumb_url: generateCdnThumb(fileName),
|
|
key: fileName
|
|
}
|
|
]
|
|
}
|
|
}).then(r => {
|
|
onSuccess({
|
|
uid: r.data.insert_documents.returning[0].id,
|
|
url: r.data.insert_documents.returning[0].thumb_url,
|
|
name: r.data.insert_documents.returning[0].name,
|
|
status: "done",
|
|
full_url: r.data.insert_documents.returning[0].url,
|
|
key: r.data.insert_documents.returning[0].key
|
|
});
|
|
notification["success"]({
|
|
message: t("documents.successes.insert")
|
|
});
|
|
});
|
|
|
|
setState({ ...state, success: true });
|
|
})
|
|
.catch(error => {
|
|
console.log("Error uploading to S3", error);
|
|
onError(error);
|
|
notification["error"]({
|
|
message: t("documents.errors.insert") + JSON.stringify(error)
|
|
});
|
|
});
|
|
})
|
|
.catch(error => {
|
|
console.log("Outside Error here.", error);
|
|
notification["error"]({
|
|
message: t("documents.errors.getpresignurl") + JSON.stringify(error)
|
|
});
|
|
});
|
|
};
|
|
|
|
const handleUpload = ev => {
|
|
const { onError, onSuccess, onProgress } = ev;
|
|
//If PDF, upload directly.
|
|
//If JPEG, resize and upload.
|
|
let key = `${shopId}/${jobId}/${ev.file.name}`;
|
|
if (ev.file.type === "application/pdf") {
|
|
console.log("It's a PDF.");
|
|
uploadToS3(key, ev.file.type, ev.file, onError, onSuccess, onProgress);
|
|
} else {
|
|
Resizer.imageFileResizer(
|
|
ev.file,
|
|
3000,
|
|
3000,
|
|
"JPEG",
|
|
75,
|
|
0,
|
|
uri => {
|
|
let file = new File([uri], ev.file.name, {});
|
|
file.uid = ev.file.uid;
|
|
uploadToS3(key, file.type, file, onError, onSuccess, onProgress);
|
|
},
|
|
"blob"
|
|
);
|
|
}
|
|
};
|
|
const handleCancel = () => setState({ ...state, previewVisible: false });
|
|
|
|
const handlePreview = async file => {
|
|
if (!file.full_url && !file.url) {
|
|
file.preview = await getBase64(file.originFileObj);
|
|
}
|
|
|
|
setState({
|
|
...state,
|
|
previewImage: file.full_url || file.url,
|
|
previewVisible: true
|
|
});
|
|
};
|
|
const handleChange = props => {
|
|
const { event, fileList, file } = props;
|
|
//Required to ensure that the state accurately reflects new data and that images can be deleted in feeded.
|
|
if (!event) {
|
|
//SPread the new file in where the old one was.
|
|
const newFileList = fileList.map(i =>
|
|
i.uid === file.uid ? Object.assign({}, i, file.response) : i
|
|
);
|
|
setFileList(newFileList);
|
|
} else {
|
|
setFileList(fileList);
|
|
}
|
|
};
|
|
|
|
const { previewVisible, previewImage } = state;
|
|
|
|
const handleRemove = file => {
|
|
console.log("file", file);
|
|
|
|
//Remove the file on S3
|
|
axios
|
|
.post("/delete_s3", { fileName: file.key })
|
|
.then(response => {
|
|
//Delete the record in our database.
|
|
if (response.status === 200) {
|
|
deleteDocument({ variables: { id: file.uid } }).then(r => {
|
|
notification["success"]({
|
|
message: t("documents.successes.delete")
|
|
});
|
|
});
|
|
} else {
|
|
notification["error"]({
|
|
message:
|
|
1 +
|
|
t("documents.errors.deletes3") +
|
|
JSON.stringify(response.message)
|
|
});
|
|
}
|
|
})
|
|
.catch(error => {
|
|
notification["error"]({
|
|
message: "2" + t("documents.errors.deletes3") + JSON.stringify(error)
|
|
});
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div className='clearfix'>
|
|
<button
|
|
onClick={() => {
|
|
const imageRequest = JSON.stringify({
|
|
bucket: process.env.REACT_APP_S3_BUCKET,
|
|
key:
|
|
"52b7357c-0edd-4c95-85c3-dfdbcdfad9ac/c8ca5761-681a-4bb3-ab76-34c447357be3/Invoice_353284489.pdf",
|
|
edits: { format: "jpeg" }
|
|
});
|
|
const CloudFrontUrl = "https://d18fc493a0fm4o.cloudfront.net";
|
|
const url = `${CloudFrontUrl}/${btoa(imageRequest)}`;
|
|
console.log("url", url);
|
|
}}>
|
|
Test PDF
|
|
</button>
|
|
<Upload.Dragger
|
|
customRequest={handleUpload}
|
|
accept='.pdf,.jpg,.jpeg'
|
|
listType='picture-card'
|
|
fileList={fileList}
|
|
multiple={true}
|
|
onPreview={handlePreview}
|
|
onRemove={handleRemove}
|
|
onChange={handleChange}>
|
|
<p className='ant-upload-drag-icon'>
|
|
<Icon type='inbox' />
|
|
</p>
|
|
<p className='ant-upload-text'>
|
|
Click or drag file to this area to upload
|
|
</p>
|
|
<p className='ant-upload-hint'>
|
|
Support for a single or bulk upload. Strictly prohibit from uploading
|
|
company data or other band files
|
|
</p>
|
|
</Upload.Dragger>
|
|
<Modal visible={previewVisible} footer={null} onCancel={handleCancel}>
|
|
<img alt='example' style={{ width: "100%" }} src={previewImage} />
|
|
</Modal>
|
|
</div>
|
|
);
|
|
}
|
|
export default JobsDocumentsComponent;
|