237 lines
7.7 KiB
JavaScript
237 lines
7.7 KiB
JavaScript
import { Button, Divider, Form, Modal, Space } from "antd";
|
|
import axios from "axios";
|
|
import React, { useEffect, useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { connect } from "react-redux";
|
|
import { createStructuredSelector } from "reselect";
|
|
import { logImEXEvent } from "../../firebase/firebase.utils";
|
|
import { toggleEmailOverlayVisible } from "../../redux/email/email.actions";
|
|
import { selectEmailConfig, selectEmailVisible } from "../../redux/email/email.selectors.js";
|
|
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
|
|
import RenderTemplate from "../../utils/RenderTemplate";
|
|
import { EmailSettings } from "../../utils/TemplateConstants";
|
|
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
|
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
|
import EmailOverlayComponent from "./email-overlay.component";
|
|
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
|
|
|
|
const mapStateToProps = createStructuredSelector({
|
|
modalVisible: selectEmailVisible,
|
|
emailConfig: selectEmailConfig,
|
|
bodyshop: selectBodyshop,
|
|
currentUser: selectCurrentUser
|
|
});
|
|
|
|
const mapDispatchToProps = (dispatch) => ({
|
|
toggleEmailOverlayVisible: () => dispatch(toggleEmailOverlayVisible())
|
|
});
|
|
|
|
export function EmailOverlayContainer({ emailConfig, modalVisible, toggleEmailOverlayVisible, bodyshop, currentUser }) {
|
|
const { t } = useTranslation();
|
|
const [form] = Form.useForm();
|
|
const [loading, setLoading] = useState(false);
|
|
const [sending, setSending] = useState(false);
|
|
const [rawHtml, setRawHtml] = useState("");
|
|
const [pdfCopytoAttach, setPdfCopytoAttach] = useState({
|
|
filename: null,
|
|
pdf: null
|
|
});
|
|
const [selectedMedia, setSelectedMedia] = useState([]);
|
|
const notification = useNotification();
|
|
|
|
const defaultEmailFrom = {
|
|
from: {
|
|
name: currentUser.displayName ? `${currentUser.displayName} @ ${bodyshop.shopname}` : bodyshop.shopname,
|
|
address: EmailSettings.fromAddress
|
|
}
|
|
};
|
|
|
|
const handleFinish = async (allValues) => {
|
|
logImEXEvent("email_send_from_modal");
|
|
|
|
//const attachments = [];
|
|
|
|
// if (values.fileList)
|
|
// await asyncForEach(values.fileList, async (f) => {
|
|
// const t = {
|
|
// ContentType: f.type,
|
|
// Filename: f.name,
|
|
// Base64Content: (await toBase64(f.originFileObj)).split(",")[1],
|
|
// };
|
|
// attachments.push(t);
|
|
// });
|
|
|
|
const { from, ...values } = allValues;
|
|
setSending(true);
|
|
try {
|
|
await axios.post("/sendemail", {
|
|
bodyshopid: bodyshop.id,
|
|
jobid: emailConfig.jobid,
|
|
|
|
...defaultEmailFrom,
|
|
ReplyTo: {
|
|
Email: from,
|
|
Name: currentUser.displayName
|
|
},
|
|
...values,
|
|
html: rawHtml,
|
|
attachments: [
|
|
...(values.fileList
|
|
? await Promise.all(
|
|
values.fileList.map(async (f) => {
|
|
return {
|
|
filename: f.name,
|
|
path: await toBase64(f.originFileObj)
|
|
};
|
|
})
|
|
)
|
|
: []),
|
|
...(pdfCopytoAttach.pdf
|
|
? [
|
|
{
|
|
path: pdfCopytoAttach.pdf,
|
|
filename: pdfCopytoAttach.filename && `${pdfCopytoAttach.filename}.pdf`
|
|
}
|
|
]
|
|
: [])
|
|
],
|
|
media: selectedMedia.filter((m) => m.isSelected).map((m) => m.fullsize)
|
|
//attachments,
|
|
});
|
|
notification["success"]({ message: t("emails.successes.sent") });
|
|
toggleEmailOverlayVisible();
|
|
} catch (error) {
|
|
notification["error"]({
|
|
message: t("emails.errors.notsent", { message: error.message })
|
|
});
|
|
}
|
|
setSending(false);
|
|
};
|
|
|
|
const render = async () => {
|
|
logImEXEvent("email_render_template", { template: emailConfig.template });
|
|
setLoading(true);
|
|
let { html, pdf, filename } = await RenderTemplate(
|
|
emailConfig.template,
|
|
bodyshop,
|
|
true,
|
|
false,
|
|
false,
|
|
notification
|
|
);
|
|
|
|
const response = await axios.post("/render/inlinecss", {
|
|
html: html,
|
|
url: `${window.location.protocol}://${window.location.host}/`
|
|
});
|
|
setRawHtml(response.data);
|
|
|
|
if (pdf) {
|
|
setPdfCopytoAttach({ pdf, filename });
|
|
}
|
|
|
|
form.setFieldsValue({
|
|
from: currentUser.validemail ? currentUser.email : bodyshop.email,
|
|
...emailConfig.messageOptions,
|
|
cc: emailConfig.messageOptions.cc && emailConfig.messageOptions.cc.filter((x) => x),
|
|
to: emailConfig.messageOptions.to && emailConfig.messageOptions.to.filter((x) => x),
|
|
html: response.data,
|
|
fileList: []
|
|
});
|
|
|
|
if (bodyshop.md_email_cc[emailConfig.template.name] && bodyshop.md_email_cc[emailConfig.template.name].length > 0) {
|
|
form.setFieldsValue({
|
|
cc: [...(form.getFieldValue("cc") || []), ...bodyshop.md_email_cc[emailConfig.template.name]]
|
|
});
|
|
}
|
|
setLoading(false);
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (modalVisible) render();
|
|
}, [modalVisible]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
return (
|
|
<Modal
|
|
destroyOnClose={true}
|
|
open={modalVisible}
|
|
maskClosable={false}
|
|
width={"80%"}
|
|
onOk={() => form.submit()}
|
|
title={t("emails.labels.emailpreview")}
|
|
onCancel={() => {
|
|
toggleEmailOverlayVisible();
|
|
}}
|
|
//closeIcon={() => null}
|
|
okText={t("general.actions.send")}
|
|
okButtonProps={{
|
|
loading: sending,
|
|
disabled:
|
|
selectedMedia &&
|
|
(selectedMedia.filter((s) => s.isSelected).reduce((acc, val) => (acc = acc + val.size), 0) >=
|
|
10485760 - new Blob([form.getFieldValue("html")]).size ||
|
|
selectedMedia.filter((s) => s.isSelected).length > 10)
|
|
}}
|
|
>
|
|
<div>
|
|
<div
|
|
style={{
|
|
// marginTop: "3rem",
|
|
display: "flex",
|
|
justifyContent: "flex-end"
|
|
}}
|
|
>
|
|
<Space style={{ alignSelf: "flex-end" }} align="right">
|
|
<Button
|
|
onClick={() => {
|
|
toggleEmailOverlayVisible();
|
|
}}
|
|
>
|
|
{t("general.actions.cancel")}
|
|
</Button>
|
|
<Button
|
|
loading={sending}
|
|
onClick={() => form.submit()}
|
|
disabled={
|
|
selectedMedia &&
|
|
(selectedMedia.filter((s) => s.isSelected).reduce((acc, val) => (acc = acc + val.size), 0) >=
|
|
10485760 - new Blob([form.getFieldValue("html")]).size ||
|
|
selectedMedia.filter((s) => s.isSelected).length > 10)
|
|
}
|
|
type="primary"
|
|
>
|
|
{t("general.actions.send")}
|
|
</Button>
|
|
</Space>
|
|
</div>
|
|
<Form layout="vertical" form={form} onFinish={handleFinish}>
|
|
{loading && (
|
|
<div>
|
|
<LoadingSkeleton />
|
|
<Divider>{t("emails.labels.preview")}</Divider>
|
|
<LoadingSpinner message={t("emails.labels.generatingemail")} />
|
|
</div>
|
|
)}
|
|
|
|
{!loading && <EmailOverlayComponent form={form} selectedMediaState={[selectedMedia, setSelectedMedia]} />}
|
|
</Form>
|
|
</div>
|
|
</Modal>
|
|
);
|
|
}
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(EmailOverlayContainer);
|
|
|
|
const toBase64 = (file) =>
|
|
new Promise((resolve, reject) => {
|
|
const reader = new FileReader();
|
|
reader.readAsDataURL(file);
|
|
reader.onload = () => resolve(reader.result);
|
|
reader.onerror = (error) => reject(error);
|
|
});
|
|
|
|
// const asyncForEach = async (array, callback) => {
|
|
// for (let index = 0; index < array.length; index++) {
|
|
// await callback(array[index], index, array);
|
|
// }
|
|
// };
|