import React, { useState, useEffect, useRef, useContext } from "react"; import * as Yup from "yup"; import { Formik, Form, Field } from "formik"; import { toast } from "react-toastify"; import { head } from "lodash"; import { makeStyles } from "@material-ui/core/styles"; import { green } from "@material-ui/core/colors"; import Button from "@material-ui/core/Button"; import IconButton from "@material-ui/core/IconButton"; import TextField from "@material-ui/core/TextField"; import Dialog from "@material-ui/core/Dialog"; import DialogActions from "@material-ui/core/DialogActions"; import DialogContent from "@material-ui/core/DialogContent"; import DialogTitle from "@material-ui/core/DialogTitle"; import CircularProgress from "@material-ui/core/CircularProgress"; import AttachFileIcon from "@material-ui/icons/AttachFile"; import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline"; import { i18n } from "../../translate/i18n"; import moment from "moment"; import api from "../../services/api"; import toastError from "../../errors/toastError"; import { Box, FormControl, Grid, InputLabel, MenuItem, Select, Tab, Tabs, } from "@material-ui/core"; import { AuthContext } from "../../context/Auth/AuthContext"; import ConfirmationModal from "../ConfirmationModal"; const useStyles = makeStyles((theme) => ({ root: { display: "flex", flexWrap: "wrap", backgroundColor: "#fff" }, tabmsg: { backgroundColor: theme.palette.campaigntab, }, textField: { marginRight: theme.spacing(1), flex: 1, }, extraAttr: { display: "flex", justifyContent: "center", alignItems: "center", }, btnWrapper: { position: "relative", }, buttonProgress: { color: green[500], position: "absolute", top: "50%", left: "50%", marginTop: -12, marginLeft: -12, }, })); const CampaignSchema = Yup.object().shape({ name: Yup.string() .min(2, i18n.t("campaigns.dialog.form.nameShort")) .max(50, i18n.t("campaigns.dialog.form.nameLong")) .required(i18n.t("campaigns.dialog.form.nameRequired")), }); const CampaignModal = ({ open, onClose, campaignId, initialValues, onSave, resetPagination, }) => { const classes = useStyles(); const isMounted = useRef(true); const { user } = useContext(AuthContext); const { companyId } = user; const [file, setFile] = useState(null); const initialState = { name: "", message1: "", message2: "", message3: "", message4: "", message5: "", status: "INATIVA", // INATIVA, PROGRAMADA, EM_ANDAMENTO, CANCELADA, FINALIZADA, scheduledAt: "", whatsappId: "", contactListId: "", tagListId: "Nenhuma", companyId, }; const [campaign, setCampaign] = useState(initialState); const [whatsapps, setWhatsapps] = useState([]); const [contactLists, setContactLists] = useState([]); const [messageTab, setMessageTab] = useState(0); const [attachment, setAttachment] = useState(null); const [confirmationOpen, setConfirmationOpen] = useState(false); const [campaignEditable, setCampaignEditable] = useState(true); const attachmentFile = useRef(null); const [tagLists, setTagLists] = useState([]); useEffect(() => { return () => { isMounted.current = false; }; }, []); useEffect(() => { (async () => { try { const { data } = await api.get("/files/", { params: { companyId } }); setFile(data.files); } catch (err) { toastError(err); } })(); }, []); useEffect(() => { if (isMounted.current) { if (initialValues) { setCampaign((prevState) => { return { ...prevState, ...initialValues }; }); } api .get(`/contact-lists/list`, { params: { companyId } }) .then(({ data }) => setContactLists(data)); api .get(`/whatsapp`, { params: { companyId, session: 0 } }) .then(({ data }) => setWhatsapps(data)); api.get(`/tags`, { params: { companyId } }) .then(({ data }) => { const fetchedTags = data.tags; // Perform any necessary data transformation here const formattedTagLists = fetchedTags.map((tag) => ({ id: tag.id, name: tag.name, })); setTagLists(formattedTagLists); }) .catch((error) => { console.error("Error retrieving tags:", error); }); if (!campaignId) return; api.get(`/campaigns/${campaignId}`).then(({ data }) => { setCampaign((prev) => { let prevCampaignData = Object.assign({}, prev); Object.entries(data).forEach(([key, value]) => { if (key === "scheduledAt" && value !== "" && value !== null) { prevCampaignData[key] = moment(value).format("YYYY-MM-DDTHH:mm"); } else { prevCampaignData[key] = value === null ? "" : value; } }); return {...prevCampaignData, tagListId: data.tagId || "Nenhuma"}; }); }); } }, [campaignId, open, initialValues, companyId]); useEffect(() => { const now = moment(); const scheduledAt = moment(campaign.scheduledAt); const moreThenAnHour = !Number.isNaN(scheduledAt.diff(now)) && scheduledAt.diff(now, "hour") > 1; const isEditable = campaign.status === "INATIVA" || (campaign.status === "PROGRAMADA" && moreThenAnHour); setCampaignEditable(isEditable); }, [campaign.status, campaign.scheduledAt]); const handleClose = () => { onClose(); setCampaign(initialState); }; const handleAttachmentFile = (e) => { const file = head(e.target.files); if (file) { setAttachment(file); } }; const handleSaveCampaign = async (values) => { try { const dataValues = {}; Object.entries(values).forEach(([key, value]) => { if (key === "scheduledAt" && value !== "" && value !== null) { dataValues[key] = moment(value).format("YYYY-MM-DD HH:mm:ss"); } else { dataValues[key] = value === "" ? null : value; } }); if (campaignId) { await api.put(`/campaigns/${campaignId}`, dataValues); if (attachment != null) { const formData = new FormData(); formData.append("file", attachment); await api.post(`/campaigns/${campaignId}/media-upload`, formData); } handleClose(); } else { const { data } = await api.post("/campaigns", dataValues); if (attachment != null) { const formData = new FormData(); formData.append("file", attachment); await api.post(`/campaigns/${data.id}/media-upload`, formData); } if (onSave) { onSave(data); } handleClose(); } toast.success(i18n.t("campaigns.toasts.success")); } catch (err) { console.log(err); toastError(err); } }; const deleteMedia = async () => { if (attachment) { setAttachment(null); attachmentFile.current.value = null; } if (campaign.mediaPath) { await api.delete(`/campaigns/${campaign.id}/media-upload`); setCampaign((prev) => ({ ...prev, mediaPath: null, mediaName: null })); toast.success(i18n.t("campaigns.toasts.deleted")); } }; const renderMessageField = (identifier) => { return ( ); }; const cancelCampaign = async () => { try { await api.post(`/campaigns/${campaign.id}/cancel`); toast.success(i18n.t("campaigns.toasts.cancel")); setCampaign((prev) => ({ ...prev, status: "CANCELADA" })); resetPagination(); } catch (err) { toast.error(err.message); } }; const restartCampaign = async () => { try { await api.post(`/campaigns/${campaign.id}/restart`); toast.success(i18n.t("campaigns.toasts.restart")); setCampaign((prev) => ({ ...prev, status: "EM_ANDAMENTO" })); resetPagination(); } catch (err) { toast.error(err.message); } }; return (
setConfirmationOpen(false)} onConfirm={deleteMedia} > {i18n.t("campaigns.confirmationModal.deleteMessage")} {campaignEditable ? ( <> {campaignId ? `${i18n.t("campaigns.dialog.update")}` : `${i18n.t("campaigns.dialog.new")}`} ) : ( <>{`${i18n.t("campaigns.dialog.readonly")}`} )}
handleAttachmentFile(e)} />
{ setTimeout(() => { handleSaveCampaign(values); actions.setSubmitting(false); }, 400); }} > {({ values, errors, touched, isSubmitting }) => (
{i18n.t("campaigns.dialog.form.contactList")} Nenhuma {contactLists && contactLists.map((contactList) => ( {contactList.name} ))} {i18n.t("campaigns.dialog.form.tagList")} Nenhuma {Array.isArray(tagLists) && tagLists.map((tagList) => ( {tagList.name} ))} {i18n.t("campaigns.dialog.form.whatsapp")} Nenhuma {whatsapps && whatsapps.map((whatsapp) => ( {whatsapp.name} ))} {i18n.t("campaigns.dialog.form.fileList")} {"Nenhum"} {file.map(f => ( {f.name} ))} setMessageTab(v)} variant="fullWidth" centered style={{ borderRadius: 2, }} > {messageTab === 0 && ( <>{renderMessageField("message1")} )} {messageTab === 1 && ( <>{renderMessageField("message2")} )} {messageTab === 2 && ( <>{renderMessageField("message3")} )} {messageTab === 3 && ( <>{renderMessageField("message4")} )} {messageTab === 4 && ( <>{renderMessageField("message5")} )} {(campaign.mediaPath || attachment) && ( {campaignEditable && ( setConfirmationOpen(true)} color="secondary" > )} )} {campaign.status === "CANCELADA" && ( )} {campaign.status === "EM_ANDAMENTO" && ( )} {!attachment && !campaign.mediaPath && campaignEditable && ( )} {(campaignEditable || campaign.status === "CANCELADA") && ( )}
)}
); }; export default CampaignModal;