mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-17 21:25:54 +02:00
refactor: handle uncuaght err in send mail
This commit is contained in:
@@ -623,5 +623,11 @@
|
||||
"generate-test-token":"Generate Test Token",
|
||||
"regenerate-test-token":"Regenerate Test Token",
|
||||
"help-test-token":"This token can be used to test the APIs at the https://sandbox.opensignlabs.com/api/v1 endpoint, allowing you to conduct unlimited document signatures. Please note that the sandbox API will sign your documents with self-signed certificates, which may not be recognized as valid by Adobe. Once you’ve completed your testing, you can upgrade to one of our paid plans to generate a production token.",
|
||||
"help-api-token":"This token can be used to access the production APIs at the {{origin}}/api/v1 endpoint. It can only be generated on one of our paid plans."
|
||||
"help-api-token":"This token can be used to access the production APIs at the {{origin}}/api/v1 endpoint. It can only be generated on one of our paid plans.",
|
||||
"Add-Webhook":"Add Webhook",
|
||||
"quotamailselfsign": "You've reached your limit of 20 emails for this month. Upgrade now to continue sending emails directly.",
|
||||
"quotamail": "You've reached your limit of 20 signature request emails for this month. Upgrade now to continue sending emails directly.",
|
||||
"quotamailTip":"Tip: You can still sign unlimited documents by manually sharing the signing request links below.",
|
||||
"quotamailhead":"Quota Reached"
|
||||
|
||||
}
|
||||
|
||||
@@ -624,5 +624,11 @@
|
||||
"generate-test-token": "Générer jeton de test",
|
||||
"regenerate-test-token":"Régénérer le jeton de test",
|
||||
"help-test-token":"Ce jeton peut être utilisé pour tester les API au niveau du point de terminaison https://sandbox.opensignlabs.com/api/v1, vous permettant ainsi d'effectuer un nombre illimité de signatures de documents. Veuillez noter que l'API sandbox signera vos documents avec des certificats auto-signés, qui peuvent ne pas être reconnus comme valides par Adobe. Une fois vos tests terminés, vous pouvez passer à l’un de nos forfaits payants pour générer un jeton de production.",
|
||||
"help-api-token":"Ce jeton peut être utilisé pour accéder aux API de production au point de terminaison {{origin}}/api/v1. Il ne peut être généré que sur l'un de nos forfaits payants."
|
||||
"help-api-token":"Ce jeton peut être utilisé pour accéder aux API de production au point de terminaison {{origin}}/api/v1. Il ne peut être généré que sur l'un de nos forfaits payants.",
|
||||
"Add-Webhook":"Ajouter Webhook",
|
||||
"quotamailselfsign": "Vous avez atteint votre limite de 20 e-mails pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.",
|
||||
"quotamail": "Vous avez atteint votre limite de 20 e-mails de demande de signature pour ce mois. Mettez à niveau maintenant pour continuer à envoyer des e-mails directement.",
|
||||
"quotamailTip":"Astuce : Vous pouvez toujours signer un nombre illimité de documents en partageant manuellement les liens de demande de signature ci-dessous.",
|
||||
"quotamailhead":"Quota atteint"
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ function EmailComponent({
|
||||
sender,
|
||||
setIsAlert,
|
||||
extUserId,
|
||||
activeMailAdapter
|
||||
activeMailAdapter,
|
||||
planCode
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [emailList, setEmailList] = useState([]);
|
||||
@@ -34,7 +35,7 @@ function EmailComponent({
|
||||
const imgPng =
|
||||
"https://qikinnovation.ams3.digitaloceanspaces.com/logo.png";
|
||||
|
||||
let url = `${localStorage.getItem("baseUrl")}functions/sendmailv3/`;
|
||||
let url = `${localStorage.getItem("baseUrl")}functions/sendmailv3`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
@@ -50,6 +51,7 @@ function EmailComponent({
|
||||
recipient: emailList[i],
|
||||
subject: `${sender.name} has signed the doc - ${pdfName}`,
|
||||
from: sender.email,
|
||||
plan: planCode,
|
||||
html:
|
||||
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /></head><body> <div style='background-color:#f5f5f5;padding:20px'> <div style='box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background-color:white;'> <div><img src=" +
|
||||
imgPng +
|
||||
@@ -74,24 +76,19 @@ function EmailComponent({
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (sendMail && sendMail.data.result.status === "success") {
|
||||
if (sendMail?.data?.result?.status === "success") {
|
||||
setSuccessEmail(true);
|
||||
setIsEmail(false);
|
||||
setTimeout(() => {
|
||||
setSuccessEmail(false);
|
||||
setIsEmail(false);
|
||||
setEmailValue("");
|
||||
setEmailList([]);
|
||||
}, 1500);
|
||||
|
||||
setIsLoading(false);
|
||||
} else if (sendMail && sendMail.data.result.status === "error") {
|
||||
} else if (sendMail?.data?.result?.status === "quota-reached") {
|
||||
setIsLoading(false);
|
||||
setIsEmail(false);
|
||||
setIsAlert({
|
||||
isShow: true,
|
||||
alertMessage: t("something-went-wrong-mssg")
|
||||
});
|
||||
setIsAlert({ isShow: true, alertMessage: "quotareached" });
|
||||
setEmailValue("");
|
||||
setEmailList([]);
|
||||
} else {
|
||||
|
||||
@@ -133,6 +133,7 @@ function PdfRequestFiles(props) {
|
||||
const [documentId, setDocumentId] = useState("");
|
||||
const [isPublicContact, setIsPublicContact] = useState(false);
|
||||
const [pdfArrayBuffer, setPdfArrayBuffer] = useState("");
|
||||
const [plancode, setPlanCode] = useState("");
|
||||
const isHeader = useSelector((state) => state.showHeader);
|
||||
const divRef = useRef(null);
|
||||
|
||||
@@ -246,6 +247,7 @@ function PdfRequestFiles(props) {
|
||||
const plan = res.plan;
|
||||
const billingDate = res?.billingDate;
|
||||
const status = res?.status;
|
||||
setPlanCode(plan);
|
||||
if (plan === "freeplan") {
|
||||
return true;
|
||||
} else if (billingDate) {
|
||||
@@ -986,6 +988,7 @@ function PdfRequestFiles(props) {
|
||||
? replaceVar?.subject
|
||||
: `${pdfDetails?.[0].ExtUserPtr.Name} has requested you to sign "${pdfDetails?.[0].Name}"`,
|
||||
from: senderEmail,
|
||||
plan: plancode,
|
||||
html: requestBody
|
||||
? replaceVar?.body
|
||||
: "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /> </head> <body> <div style='background-color: #f5f5f5; padding: 20px'=> <div style=' box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background: white;padding-bottom: 20px;'> <div style='padding:10px 10px 0 10px'><img src=" +
|
||||
|
||||
@@ -61,6 +61,7 @@ import PdfZoom from "../components/pdf/PdfZoom";
|
||||
import LottieWithLoader from "../primitives/DotLottieReact";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import RotateAlert from "../components/RotateAlert";
|
||||
import QuotaCard from "../primitives/QuotaCard";
|
||||
|
||||
function PlaceHolderSign() {
|
||||
const { t } = useTranslation();
|
||||
@@ -150,8 +151,8 @@ function PlaceHolderSign() {
|
||||
const [isCustomize, setIsCustomize] = useState(false);
|
||||
const [zoomPercent, setZoomPercent] = useState(0);
|
||||
const [scale, setScale] = useState(1);
|
||||
|
||||
const [pdfRotateBase64, setPdfRotatese64] = useState("");
|
||||
const [planCode, setPlanCode] = useState("");
|
||||
const isMobile = window.innerWidth < 767;
|
||||
const [, drop] = useDrop({
|
||||
accept: "BOX",
|
||||
@@ -240,6 +241,7 @@ function PlaceHolderSign() {
|
||||
const res = await fetchSubscription();
|
||||
const plan = res.plan;
|
||||
const billingDate = res.billingDate;
|
||||
setPlanCode(plan);
|
||||
if (plan === "freeplan") {
|
||||
return true;
|
||||
} else if (billingDate) {
|
||||
@@ -1058,7 +1060,7 @@ function PlaceHolderSign() {
|
||||
try {
|
||||
const imgPng =
|
||||
"https://qikinnovation.ams3.digitaloceanspaces.com/logo.png";
|
||||
let url = `${localStorage.getItem("baseUrl")}functions/sendmailv3/`;
|
||||
let url = `${localStorage.getItem("baseUrl")}functions/sendmailv3`;
|
||||
const headers = {
|
||||
"Content-Type": "application/json",
|
||||
"X-Parse-Application-Id": localStorage.getItem("parseAppId"),
|
||||
@@ -1113,6 +1115,7 @@ function PlaceHolderSign() {
|
||||
? replaceVar?.subject
|
||||
: `${senderName} has requested you to sign "${documentName}"`,
|
||||
from: senderEmail,
|
||||
plan: planCode,
|
||||
html: isCustomize
|
||||
? replaceVar?.body
|
||||
: "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8' /> </head> <body> <div style='background-color: #f5f5f5; padding: 20px'=> <div style=' box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 12px;background: white;padding-bottom: 20px;'> <div style='padding:10px 10px 0 10px'><img src=" +
|
||||
@@ -1143,7 +1146,7 @@ function PlaceHolderSign() {
|
||||
console.log("error", error);
|
||||
}
|
||||
}
|
||||
if (sendMail.data.result.status === "success") {
|
||||
if (sendMail?.data?.result?.status === "success") {
|
||||
setMailStatus("success");
|
||||
try {
|
||||
let data;
|
||||
@@ -1156,9 +1159,8 @@ function PlaceHolderSign() {
|
||||
} else {
|
||||
data = { SendMail: true };
|
||||
}
|
||||
|
||||
await axios
|
||||
.put(
|
||||
try {
|
||||
await axios.put(
|
||||
`${localStorage.getItem(
|
||||
"baseUrl"
|
||||
)}classes/contracts_Document/${documentId}`,
|
||||
@@ -1170,21 +1172,21 @@ function PlaceHolderSign() {
|
||||
"X-Parse-Session-Token": localStorage.getItem("accesstoken")
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
console.log("axois err ", err);
|
||||
});
|
||||
);
|
||||
} catch (err) {
|
||||
console.log("axois err ", err);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("error", e);
|
||||
}
|
||||
|
||||
setIsSend(true);
|
||||
setIsMailSend(true);
|
||||
const loadObj = {
|
||||
isLoad: false
|
||||
};
|
||||
setIsLoading(loadObj);
|
||||
setIsLoading({ isLoad: false });
|
||||
setIsUiLoading(false);
|
||||
} else if (sendMail?.data?.result?.status === "quota-reached") {
|
||||
setMailStatus("quotareached");
|
||||
setIsSend(true);
|
||||
setIsMailSend(true);
|
||||
setIsUiLoading(false);
|
||||
} else {
|
||||
setMailStatus("failed");
|
||||
@@ -1829,7 +1831,7 @@ function PlaceHolderSign() {
|
||||
<span className="ml-[5px] mr-[5px]">{t("or")}</span>
|
||||
<span className="h-[1px] w-[20%] bg-[#ccc]"></span>
|
||||
</div>
|
||||
<div className="mt-3 mb-3">{handleShareList()}</div>
|
||||
<div className="my-3">{handleShareList()}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
@@ -1838,7 +1840,11 @@ function PlaceHolderSign() {
|
||||
{/* this modal is used show send mail message and after send mail success message */}
|
||||
<ModalUi
|
||||
isOpen={isSend}
|
||||
title={t("Mails Sent")}
|
||||
title={
|
||||
mailStatus === "quotareached"
|
||||
? t("quotamailhead")
|
||||
: t("Mails Sent")
|
||||
}
|
||||
handleClose={() => {
|
||||
setIsSend(false);
|
||||
setSignerPos([]);
|
||||
@@ -1852,40 +1858,53 @@ function PlaceHolderSign() {
|
||||
<p>{t("placeholder-alert-4")}</p>
|
||||
{isCurrUser && <p>{t("placeholder-alert-5")}</p>}
|
||||
</div>
|
||||
) : mailStatus === "quotareached" ? (
|
||||
<div className="flex flex-col gap-y-3">
|
||||
<QuotaCard
|
||||
handleClose={() => {
|
||||
setIsSend(false);
|
||||
setSignerPos([]);
|
||||
navigate("/report/1MwEuxLEkF");
|
||||
}}
|
||||
/>
|
||||
<div className="my-3">{handleShareList()}</div>
|
||||
</div>
|
||||
) : (
|
||||
<p>{t("placeholder-alert-6")}</p>
|
||||
)}
|
||||
{!mailStatus && (
|
||||
<div className="w-full h-[1px] bg-[#9f9f9f] my-[15px]"></div>
|
||||
)}
|
||||
<div
|
||||
className={
|
||||
mailStatus === "success"
|
||||
? "flex justify-center mt-1"
|
||||
: ""
|
||||
}
|
||||
>
|
||||
{isCurrUser && (
|
||||
<button
|
||||
onClick={() => handleRecipientSign()}
|
||||
type="button"
|
||||
className="op-btn op-btn-primary mr-1"
|
||||
>
|
||||
{t("yes")}
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={() => {
|
||||
setIsSend(false);
|
||||
setSignerPos([]);
|
||||
navigate("/report/1MwEuxLEkF");
|
||||
}}
|
||||
type="button"
|
||||
className="op-btn op-btn-ghost"
|
||||
{mailStatus !== "quotareached" && (
|
||||
<div
|
||||
className={
|
||||
mailStatus === "success"
|
||||
? "flex justify-center mt-1"
|
||||
: ""
|
||||
}
|
||||
>
|
||||
{isCurrUser ? t("no") : t("close")}
|
||||
</button>
|
||||
</div>
|
||||
{isCurrUser && (
|
||||
<button
|
||||
onClick={() => handleRecipientSign()}
|
||||
type="button"
|
||||
className="op-btn op-btn-primary mr-1"
|
||||
>
|
||||
{t("yes")}
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={() => {
|
||||
setIsSend(false);
|
||||
setSignerPos([]);
|
||||
navigate("/report/1MwEuxLEkF");
|
||||
}}
|
||||
type="button"
|
||||
className="op-btn op-btn-ghost"
|
||||
>
|
||||
{isCurrUser ? t("no") : t("close")}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</ModalUi>
|
||||
<ModalUi
|
||||
|
||||
@@ -57,6 +57,7 @@ import PdfZoom from "../components/pdf/PdfZoom";
|
||||
import Loader from "../primitives/Loader";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import RotateAlert from "../components/RotateAlert";
|
||||
import QuotaCard from "../primitives/QuotaCard";
|
||||
//For signYourself inProgress section signer can add sign and complete doc sign.
|
||||
function SignYourSelf() {
|
||||
const { t } = useTranslation();
|
||||
@@ -128,56 +129,37 @@ function SignYourSelf() {
|
||||
const isHeader = useSelector((state) => state.showHeader);
|
||||
const [scale, setScale] = useState(1);
|
||||
const [pdfRotateBase64, setPdfRotatese64] = useState("");
|
||||
const [isRotate, setIsRotate] = useState({
|
||||
status: false,
|
||||
degree: 0
|
||||
});
|
||||
const [isRotate, setIsRotate] = useState({ status: false, degree: 0 });
|
||||
const [isSubscribe, setIsSubscribe] = useState({ plan: "", isValid: true });
|
||||
const divRef = useRef(null);
|
||||
const nodeRef = useRef(null);
|
||||
const [, drop] = useDrop({
|
||||
accept: "BOX",
|
||||
drop: (item, monitor) => addPositionOfSignature(item, monitor),
|
||||
collect: (monitor) => ({
|
||||
isOver: !!monitor.isOver()
|
||||
})
|
||||
collect: (monitor) => ({ isOver: !!monitor.isOver() })
|
||||
});
|
||||
const pdfRef = useRef();
|
||||
const [{ isDragSign }, dragSignature] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
id: 1,
|
||||
text: "signature"
|
||||
},
|
||||
collect: (monitor) => ({
|
||||
isDragSign: !!monitor.isDragging()
|
||||
})
|
||||
item: { id: 1, text: "signature" },
|
||||
collect: (monitor) => ({ isDragSign: !!monitor.isDragging() })
|
||||
});
|
||||
|
||||
const [{ isDragStamp }, dragStamp] = useDrag({
|
||||
type: "BOX",
|
||||
item: {
|
||||
id: 2,
|
||||
text: "stamp"
|
||||
},
|
||||
|
||||
collect: (monitor) => ({
|
||||
isDragStamp: !!monitor.isDragging()
|
||||
})
|
||||
item: { id: 2, text: "stamp" },
|
||||
collect: (monitor) => ({ isDragStamp: !!monitor.isDragging() })
|
||||
});
|
||||
|
||||
const index = xyPostion?.findIndex((object) => {
|
||||
return object.pageNumber === pageNumber;
|
||||
});
|
||||
// rowlevel={JSON.parse(localStorage.getItem("rowlevel"))}
|
||||
const rowLevel =
|
||||
localStorage.getItem("rowlevel") &&
|
||||
JSON.parse(localStorage.getItem("rowlevel"));
|
||||
|
||||
const signObjId =
|
||||
rowLevel && rowLevel?.id
|
||||
? rowLevel.id
|
||||
: rowLevel?.objectId && rowLevel.objectId;
|
||||
|
||||
const documentId = docId ? docId : signObjId && signObjId;
|
||||
const senderUser =
|
||||
localStorage.getItem(
|
||||
@@ -217,6 +199,12 @@ function SignYourSelf() {
|
||||
|
||||
//function for get document details for perticular signer with signer'object id
|
||||
const getDocumentDetails = async (showComplete) => {
|
||||
try {
|
||||
const subscribe = await checkIsSubscribed();
|
||||
setIsSubscribe(subscribe);
|
||||
} catch (err) {
|
||||
console.log("err in fetch sub", err);
|
||||
}
|
||||
try {
|
||||
let isCompleted;
|
||||
//getting document details
|
||||
@@ -585,8 +573,7 @@ function SignYourSelf() {
|
||||
docCls.id = documentId;
|
||||
docCls.set("Placeholders", xyPostion);
|
||||
docCls.set("IsSignyourself", true);
|
||||
const res = await docCls.save();
|
||||
console.log("Res", res);
|
||||
await docCls.save();
|
||||
} catch (e) {
|
||||
console.log("error", e);
|
||||
alert(t("something-went-wrong-mssg"));
|
||||
@@ -730,7 +717,7 @@ function SignYourSelf() {
|
||||
//function for get digital signature
|
||||
const signPdfFun = async (base64Url, documentId) => {
|
||||
let isCustomCompletionMail = false;
|
||||
const getIsSubscribe = await checkIsSubscribed();
|
||||
|
||||
const tenantDetails = await getTenantDetails(jsonSender.objectId);
|
||||
if (tenantDetails && tenantDetails === "user does not exist!") {
|
||||
alert(t("user-not-exist"));
|
||||
@@ -738,7 +725,7 @@ function SignYourSelf() {
|
||||
if (
|
||||
tenantDetails?.CompletionBody &&
|
||||
tenantDetails?.CompletionSubject &&
|
||||
getIsSubscribe.isValid
|
||||
isSubscribe?.isValid
|
||||
) {
|
||||
isCustomCompletionMail = true;
|
||||
}
|
||||
@@ -1255,14 +1242,29 @@ function SignYourSelf() {
|
||||
<div className="w-full md:w-[95%]">
|
||||
<ModalUi
|
||||
isOpen={isAlert.isShow}
|
||||
title={isAlert?.header || t("alert")}
|
||||
title={
|
||||
isAlert.alertMessage === "quotareached"
|
||||
? false
|
||||
: isAlert?.header || t("alert")
|
||||
}
|
||||
handleClose={() =>
|
||||
setIsAlert({ isShow: false, alertMessage: "" })
|
||||
isAlert.alertMessage === "quotareached"
|
||||
? false
|
||||
: setIsAlert({ isShow: false, alertMessage: "" })
|
||||
}
|
||||
>
|
||||
<div className="p-[20px] h-full">
|
||||
<p>{isAlert.alertMessage}</p>
|
||||
</div>
|
||||
{isAlert.alertMessage === "quotareached" ? (
|
||||
<QuotaCard
|
||||
isSignyourself={true}
|
||||
handlClose={() =>
|
||||
setIsAlert({ isShow: false, alertMessage: "" })
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<div className="p-[20px] h-full">
|
||||
<p>{isAlert.alertMessage}</p>
|
||||
</div>
|
||||
)}
|
||||
</ModalUi>
|
||||
|
||||
{/* this modal is used show this document is already sign */}
|
||||
@@ -1342,6 +1344,7 @@ function SignYourSelf() {
|
||||
setIsAlert={setIsAlert}
|
||||
extUserId={extUserId}
|
||||
activeMailAdapter={activeMailAdapter}
|
||||
planCode={isSubscribe?.plan}
|
||||
/>
|
||||
{/* pdf header which contain funish back button */}
|
||||
<Header
|
||||
|
||||
@@ -10,7 +10,6 @@ import Tooltip from "../primitives/Tooltip";
|
||||
import Loader from "../primitives/Loader";
|
||||
import SubscribeCard from "../primitives/SubscribeCard";
|
||||
import Tour from "reactour";
|
||||
import { validplan } from "../json/plansArr";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
function Webhook() {
|
||||
@@ -90,7 +89,7 @@ function Webhook() {
|
||||
};
|
||||
|
||||
const handleModal = () => {
|
||||
if (!validplan[isSubscribe.plan] && isEnableSubscription) {
|
||||
if (!isSubscribe?.isValid && isEnableSubscription) {
|
||||
setIsTour(true);
|
||||
} else {
|
||||
setIsModal(!isModal);
|
||||
@@ -146,7 +145,7 @@ function Webhook() {
|
||||
</div>
|
||||
<ModalUi
|
||||
isOpen={isModal}
|
||||
title={"Regenerate Token"}
|
||||
title={t("Add-Webhook")}
|
||||
handleClose={handleModal}
|
||||
>
|
||||
{error && <Alert type="danger">{error}</Alert>}
|
||||
@@ -178,7 +177,7 @@ function Webhook() {
|
||||
</div>
|
||||
</ModalUi>
|
||||
</div>
|
||||
{!validplan[isSubscribe.plan] && isEnableSubscription && (
|
||||
{!isSubscribe?.isValid && isEnableSubscription && (
|
||||
<div data-tut="webhooksubscribe">
|
||||
<SubscribeCard plan_code={isSubscribe.plan} />
|
||||
</div>
|
||||
|
||||
@@ -21,9 +21,11 @@ const ModalUi = ({
|
||||
>
|
||||
{showHeader && (
|
||||
<>
|
||||
<h3 className="text-base-content font-bold text-lg pt-[15px] px-[20px]">
|
||||
{title}
|
||||
</h3>
|
||||
{title && (
|
||||
<h3 className="text-base-content font-bold text-lg pt-[15px] px-[20px]">
|
||||
{title}
|
||||
</h3>
|
||||
)}
|
||||
{showClose && (
|
||||
<button
|
||||
className="op-btn op-btn-sm op-btn-circle op-btn-ghost text-base-content absolute right-2 top-2"
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const QuotaCard = ({ isSignyourself, handlClose }) => {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
return isSignyourself ? (
|
||||
<>
|
||||
<div
|
||||
className="op-btn op-btn-sm op-btn-circle op-btn-ghost text-primary-content absolute right-2 top-2 z-40"
|
||||
onClick={() => handlClose && handlClose()}
|
||||
>
|
||||
✕
|
||||
</div>
|
||||
<div className="op-card op-bg-primary text-primary-content w-full shadow-lg">
|
||||
<div className="op-card-body">
|
||||
<h2 className="op-card-title">
|
||||
{t("upgrade-to") + " Paid " + t("plan")}
|
||||
</h2>
|
||||
<p className="text-primary-content">{t("quotamailselfsign")}</p>
|
||||
<div className="op-card-actions justify-end">
|
||||
<button
|
||||
onClick={() => navigate("/subscription")}
|
||||
className="op-btn op-btn-accent"
|
||||
>
|
||||
{t("upgrade-now")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="op-card op-bg-primary text-primary-content w-full shadow-lg">
|
||||
<div className="op-card-body">
|
||||
<p className="text-primary-content">{t("quotamail")}</p>
|
||||
<p className="text-primary-content">{t("quotamailTip")}</p>
|
||||
<div className="op-card-actions justify-end">
|
||||
<button
|
||||
onClick={() => navigate("/subscription")}
|
||||
className="op-btn op-btn-accent"
|
||||
>
|
||||
{t("upgrade-now")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default QuotaCard;
|
||||
@@ -91,7 +91,7 @@ const saveDataFile = async (size, fileUrl, tenantPtr) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const updateMailCount = async extUserId => {
|
||||
export const updateMailCount = async (extUserId, plan, monthchange) => {
|
||||
// Update count in contracts_Users class
|
||||
const query = new Parse.Query('contracts_Users');
|
||||
query.equalTo('objectId', extUserId);
|
||||
@@ -100,13 +100,23 @@ export const updateMailCount = async extUserId => {
|
||||
const contractUser = await query.first({ useMasterKey: true });
|
||||
if (contractUser) {
|
||||
contractUser.increment('EmailCount', 1);
|
||||
if (plan === 'freeplan') {
|
||||
if (monthchange) {
|
||||
contractUser.set('LastEmailCountReset', new Date());
|
||||
contractUser.set('MontlyfreeEmails', 1);
|
||||
} else {
|
||||
if (contractUser?.get('MontlyfreeEmails')) {
|
||||
contractUser.increment('MontlyfreeEmails', 1);
|
||||
if (contractUser?.get('LastEmailCountReset')) {
|
||||
contractUser.set('LastEmailCountReset', new Date());
|
||||
}
|
||||
} else {
|
||||
contractUser.set('MontlyfreeEmails', 1);
|
||||
contractUser.set('LastEmailCountReset', new Date());
|
||||
}
|
||||
}
|
||||
}
|
||||
await contractUser.save(null, { useMasterKey: true });
|
||||
} else {
|
||||
// Create new entry if not found
|
||||
const ContractsUsers = Parse.Object.extend('contracts_Users');
|
||||
const newContractUser = new ContractsUsers();
|
||||
newContractUser.set('EmailCount', 1);
|
||||
await newContractUser.save(null, { useMasterKey: true });
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Error updating EmailCount in contracts_Users: ' + error.message);
|
||||
|
||||
@@ -142,8 +142,7 @@ export default async function sendMailGmailProvider(_extRes, template) {
|
||||
raw: email,
|
||||
},
|
||||
});
|
||||
// console.log('response ', response);
|
||||
|
||||
console.log('gmail provider res: ', response?.status);
|
||||
return { code: 200, message: 'Email sent successfully' };
|
||||
} catch (error) {
|
||||
console.error('Error sending email:', error);
|
||||
|
||||
@@ -6,7 +6,7 @@ import Mailgun from 'mailgun.js';
|
||||
import { smtpenable, smtpsecure, updateMailCount, useLocal } from '../../Utils.js';
|
||||
import sendMailGmailProvider from './sendMailGmailProvider.js';
|
||||
import { createTransport } from 'nodemailer';
|
||||
async function sendMailProvider(req) {
|
||||
async function sendMailProvider(req, plan, monthchange) {
|
||||
const mailgunApiKey = process.env.MAILGUN_API_KEY;
|
||||
try {
|
||||
let transporterSMTP;
|
||||
@@ -69,18 +69,23 @@ async function sendMailProvider(req) {
|
||||
};
|
||||
|
||||
let attachment;
|
||||
// `certificateBuffer` used to create buffer from pdf file
|
||||
try {
|
||||
const certificateBuffer = fs.readFileSync('./exports/certificate.pdf');
|
||||
const certificate = {
|
||||
filename: 'certificate.pdf',
|
||||
content: smtpenable ? certificateBuffer : undefined, //fs.readFileSync('./exports/exported_file_1223.pdf'),
|
||||
data: smtpenable ? undefined : certificateBuffer,
|
||||
};
|
||||
attachment = [file, certificate];
|
||||
} catch (err) {
|
||||
const certificatePath = './exports/certificate.pdf';
|
||||
if (fs.existsSync(certificatePath)) {
|
||||
try {
|
||||
// `certificateBuffer` used to create buffer from pdf file
|
||||
const certificateBuffer = fs.readFileSync(certificatePath);
|
||||
const certificate = {
|
||||
filename: 'certificate.pdf',
|
||||
content: smtpenable ? certificateBuffer : undefined, //fs.readFileSync('./exports/exported_file_1223.pdf'),
|
||||
data: smtpenable ? undefined : certificateBuffer,
|
||||
};
|
||||
attachment = [file, certificate];
|
||||
} catch (err) {
|
||||
attachment = [file];
|
||||
console.log('Err in read certificate sendmailv3', err);
|
||||
}
|
||||
} else {
|
||||
attachment = [file];
|
||||
console.log('Err in read certificate sendmailv3', err);
|
||||
}
|
||||
const from = req.params.from || '';
|
||||
const mailsender = smtpenable ? process.env.SMTP_USER_EMAIL : process.env.MAILGUN_SENDER;
|
||||
@@ -96,38 +101,44 @@ async function sendMailProvider(req) {
|
||||
};
|
||||
if (transporterSMTP) {
|
||||
const res = await transporterSMTP.sendMail(messageParams);
|
||||
console.log('Res ', res);
|
||||
console.log('smtp transporter res: ', res?.response);
|
||||
if (!res.err) {
|
||||
if (req.params?.extUserId) {
|
||||
await updateMailCount(req.params.extUserId);
|
||||
await updateMailCount(req.params.extUserId, plan, monthchange);
|
||||
}
|
||||
try {
|
||||
fs.unlinkSync('./exports/certificate.pdf');
|
||||
} catch (err) {
|
||||
console.log('Err in unlink certificate sendmailv3');
|
||||
if (fs.existsSync(certificatePath)) {
|
||||
try {
|
||||
fs.unlinkSync(certificatePath);
|
||||
} catch (err) {
|
||||
console.log('Err in unlink certificate sendmailv3');
|
||||
}
|
||||
}
|
||||
return { status: 'success' };
|
||||
}
|
||||
} else {
|
||||
if (mailgunApiKey) {
|
||||
const res = await mailgunClient.messages.create(mailgunDomain, messageParams);
|
||||
console.log('Res ', res);
|
||||
console.log('mailgun res: ', res?.status);
|
||||
if (res.status === 200) {
|
||||
if (req.params?.extUserId) {
|
||||
await updateMailCount(req.params.extUserId);
|
||||
await updateMailCount(req.params.extUserId, plan, monthchange);
|
||||
}
|
||||
try {
|
||||
fs.unlinkSync('./exports/certificate.pdf');
|
||||
} catch (err) {
|
||||
console.log('Err in unlink certificate sendmailv3');
|
||||
if (fs.existsSync(certificatePath)) {
|
||||
try {
|
||||
fs.unlinkSync(certificatePath);
|
||||
} catch (err) {
|
||||
console.log('Err in unlink certificate sendmailv3');
|
||||
}
|
||||
}
|
||||
return { status: 'success' };
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
fs.unlinkSync('./exports/certificate.pdf');
|
||||
} catch (err) {
|
||||
console.log('Err in unlink certificate sendmailv3');
|
||||
if (fs.existsSync(certificatePath)) {
|
||||
try {
|
||||
fs.unlinkSync(certificatePath);
|
||||
} catch (err) {
|
||||
console.log('Err in unlink certificate sendmailv3');
|
||||
}
|
||||
}
|
||||
return { status: 'error' };
|
||||
}
|
||||
@@ -147,20 +158,20 @@ async function sendMailProvider(req) {
|
||||
|
||||
if (transporterSMTP) {
|
||||
const res = await transporterSMTP.sendMail(messageParams);
|
||||
console.log('Res ', res);
|
||||
console.log('smtp transporter res: ', res?.response);
|
||||
if (!res.err) {
|
||||
if (req.params?.extUserId) {
|
||||
await updateMailCount(req.params.extUserId);
|
||||
await updateMailCount(req.params.extUserId, plan, monthchange);
|
||||
}
|
||||
return { status: 'success' };
|
||||
}
|
||||
} else {
|
||||
if (mailgunApiKey) {
|
||||
const res = await mailgunClient.messages.create(mailgunDomain, messageParams);
|
||||
console.log('Res ', res);
|
||||
console.log('mailgun res: ', res?.status);
|
||||
if (res.status === 200) {
|
||||
if (req.params?.extUserId) {
|
||||
await updateMailCount(req.params.extUserId);
|
||||
await updateMailCount(req.params.extUserId, plan, monthchange);
|
||||
}
|
||||
return { status: 'success' };
|
||||
}
|
||||
@@ -180,6 +191,7 @@ async function sendmailv3(req) {
|
||||
const mailProvider = req.params.mailProvider || 'default';
|
||||
if (mailProvider) {
|
||||
try {
|
||||
const Plan = req.params.plan;
|
||||
const extUserId = req.params.extUserId || '';
|
||||
const pdfName = req.params.pdfName || '';
|
||||
const template = {
|
||||
@@ -203,8 +215,31 @@ async function sendmailv3(req) {
|
||||
return { status: 'error' };
|
||||
}
|
||||
} else {
|
||||
const nonCustomMail = await sendMailProvider(req);
|
||||
return nonCustomMail;
|
||||
if (Plan && Plan === 'freeplan') {
|
||||
let MontlyfreeEmails = _extRes?.MontlyfreeEmails || 0;
|
||||
if (_extRes?.LastEmailCountReset?.iso) {
|
||||
const lastDate = new Date(_extRes?.LastEmailCountReset?.iso);
|
||||
const newDate = new Date();
|
||||
const isMonthChange = newDate.getMonth() > lastDate.getMonth();
|
||||
if (isMonthChange) {
|
||||
const nonCustomMail = await sendMailProvider(req, Plan, true);
|
||||
return nonCustomMail;
|
||||
} else {
|
||||
if (MontlyfreeEmails >= 20) {
|
||||
return { status: 'quota-reached' };
|
||||
} else {
|
||||
const nonCustomMail = await sendMailProvider(req, Plan);
|
||||
return nonCustomMail;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const nonCustomMail = await sendMailProvider(req, Plan);
|
||||
return nonCustomMail;
|
||||
}
|
||||
} else {
|
||||
const nonCustomMail = await sendMailProvider(req, '');
|
||||
return nonCustomMail;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
Reference in New Issue
Block a user