Files
bodyshop/client/src/components/email-overlay/email-overlay.container.jsx

176 lines
5.0 KiB
JavaScript

import { Modal, notification } 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 } from "../../redux/user/user.selectors";
import RenderTemplate from "../../utils/RenderTemplate";
import { EmailSettings } from "../../utils/TemplateConstants";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import EmailOverlayComponent from "./email-overlay.component";
const mapStateToProps = createStructuredSelector({
modalVisible: selectEmailVisible,
emailConfig: selectEmailConfig,
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
toggleEmailOverlayVisible: () => dispatch(toggleEmailOverlayVisible()),
});
export function EmailOverlayContainer({
emailConfig,
modalVisible,
toggleEmailOverlayVisible,
bodyshop,
}) {
const { t } = useTranslation();
const [loading, setLoading] = useState(false);
const [sending, setSending] = useState(false);
const defaultEmailFrom = {
from: {
name: bodyshop.shopname || EmailSettings.fromNameDefault,
address: EmailSettings.fromAddress,
},
replyTo: bodyshop.email,
};
const [messageOptions, setMessageOptions] = useState({
...defaultEmailFrom,
html: "",
fileList: [],
});
const handleOk = async () => {
logImEXEvent("email_send_from_modal");
const attachments = [];
await asyncForEach(messageOptions.fileList, async (f) => {
const t = {
ContentType: f.type,
Filename: f.name,
Base64Content: (await toBase64(f)).split(",")[1],
};
attachments.push(t);
});
console.log("messageOptions", messageOptions);
setSending(true);
try {
await axios.post("/sendemail", { ...messageOptions, attachments });
notification["success"]({ message: t("emails.successes.sent") });
toggleEmailOverlayVisible();
} catch (error) {
console.log(JSON.stringify(error));
notification["error"]({
message: t("emails.errors.notsent", { message: error.message }),
});
}
setSending(false);
};
const handleConfigChange = (event) => {
const { name, value } = event.target;
setMessageOptions({ ...messageOptions, [name]: value });
};
const handleHtmlChange = (text) => {
setMessageOptions({ ...messageOptions, html: text });
};
const handleToChange = (recipients) => {
setMessageOptions({ ...messageOptions, to: recipients });
};
const handleUpload = (file) => {
setMessageOptions({
...messageOptions,
fileList: [...messageOptions.fileList, file],
});
return false;
};
const handleFileRemove = (file) => {
setMessageOptions((state) => {
const index = state.fileList.indexOf(file);
const newfileList = state.fileList.slice();
newfileList.splice(index, 1);
return {
fileList: newfileList,
};
});
};
const render = async () => {
logImEXEvent("email_render_template", { template: emailConfig.template });
setLoading(true);
let html = await RenderTemplate(emailConfig.template, bodyshop);
setMessageOptions({
...emailConfig.messageOptions,
...defaultEmailFrom,
html: html,
fileList: [],
});
setLoading(false);
};
useEffect(() => {
if (modalVisible) render();
}, [modalVisible]); // eslint-disable-line react-hooks/exhaustive-deps
return (
<Modal
destroyOnClose={true}
visible={modalVisible}
width={"80%"}
onOk={handleOk}
onCancel={() => {
toggleEmailOverlayVisible();
}}
okButtonProps={{ loading: sending }}
>
<LoadingSpinner loading={loading}>
<EmailOverlayComponent
handleConfigChange={handleConfigChange}
messageOptions={messageOptions}
handleHtmlChange={handleHtmlChange}
handleUpload={handleUpload}
handleFileRemove={handleFileRemove}
handleToChange={handleToChange}
/>
<button
onClick={() => {
navigator.clipboard.writeText(messageOptions.html);
}}
>
Copy HTML
</button>
</LoadingSpinner>
</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);
}
};