diff --git a/apps/OpenSign/src/components/Header.js b/apps/OpenSign/src/components/Header.js index 94737f8a7..2b1a477cb 100644 --- a/apps/OpenSign/src/components/Header.js +++ b/apps/OpenSign/src/components/Header.js @@ -176,6 +176,14 @@ const Header = ({ showSidebar }) => { > Change Password +
  • { + window.open("https://console.opensignlabs.com/"); + }} + > + Console +
  • 0 ? widgetHeight : 0) : widgetHeight; if (signyourself) { diff --git a/apps/OpenSign/src/json/ReportJson.js b/apps/OpenSign/src/json/ReportJson.js index 21066f669..35553130f 100644 --- a/apps/OpenSign/src/json/ReportJson.js +++ b/apps/OpenSign/src/json/ReportJson.js @@ -320,7 +320,10 @@ export default function reportJson(id) { textColor: "white", btnIcon: "fa fa-plus", redirectUrl: "placeHolderSign", - action: "redirect" + action: "redirect", + selector: "reactourSecond", + message: + "Click the 'Use' button to create a new document from an existing template. " }, { btnId: "2234", @@ -329,6 +332,9 @@ export default function reportJson(id) { textColor: "black", btnIcon: "fa-solid fa-ellipsis-vertical fa-lg", action: "option", + selector: "reactourThird", + message: + "This menu reveals more options such as Edit & Delete. Use the 'Edit' button to add signer roles, modify fields, and update your template. Changes will apply to all future documents created from this template but won’t affect existing documents.Use the Delete button you can delete template. ", subaction: [ { btnId: "2434", diff --git a/apps/OpenSign/src/pages/Opensigndrive.js b/apps/OpenSign/src/pages/Opensigndrive.js index ac31379e1..0803cb8bb 100644 --- a/apps/OpenSign/src/pages/Opensigndrive.js +++ b/apps/OpenSign/src/pages/Opensigndrive.js @@ -129,40 +129,6 @@ function Opensigndrive() { ), position: "top", style: { fontSize: "13px" } - }, - - { - selector: '[data-tut="reactourFifth"]', - content: () => ( - - ), - position: "bottom", - style: { fontSize: "13px" } - }, - { - selector: '[data-tut="reactourSixth"]', - content: () => ( - - ), - position: "bottom", - style: { fontSize: "13px" } - }, - { - selector: '[data-tut="reactourSeventh"]', - content: () => ( - - ), - position: "bottom", - style: { fontSize: "13px" } } ]; //function for get all pdf document list @@ -177,7 +143,42 @@ function Opensigndrive() { if (driveDetails && driveDetails === "Error: Something went wrong!") { setHandleError("Error: Something went wrong!"); } else if (driveDetails && driveDetails.length > 0) { - let newTour = tourConfigs; + const addMoreTour = [ + { + selector: '[data-tut="reactourFifth"]', + content: () => ( + + ), + position: "bottom", + style: { fontSize: "13px" } + }, + { + selector: '[data-tut="reactourSixth"]', + content: () => ( + + ), + position: "bottom", + style: { fontSize: "13px" } + }, + { + selector: '[data-tut="reactourSeventh"]', + content: () => ( + + ), + position: "bottom", + style: { fontSize: "13px" } + } + ]; + let newTour = [...tourConfigs, ...addMoreTour]; const isFolderExist = driveDetails.some( (data) => data.Type === "Folder" ); @@ -195,6 +196,8 @@ function Opensigndrive() { setTourData(newTour); setSkip((prevSkip) => prevSkip + limit); sortingData(null, null, driveDetails, true); + } else { + setTourData(tourConfigs); } if (!docId) { setFolderName([{ name: "OpenSign™ Drive", objectId: "" }]); @@ -696,14 +699,17 @@ function Opensigndrive() { ) : ( <>
    - + {tourData && ( + + )} +
    handleMouseEnter(e)} diff --git a/apps/OpenSign/src/pages/PdfRequestFiles.js b/apps/OpenSign/src/pages/PdfRequestFiles.js index 8d8395cc3..df9581014 100644 --- a/apps/OpenSign/src/pages/PdfRequestFiles.js +++ b/apps/OpenSign/src/pages/PdfRequestFiles.js @@ -75,6 +75,7 @@ function PdfRequestFiles() { isShow: false, alertMessage: "" }); + const [isSubscribed, setIsSubscribed] = useState(false); const [isCompleted, setIsCompleted] = useState({ isCertificate: false, isModal: false @@ -94,7 +95,7 @@ function PdfRequestFiles() { const [minRequiredCount, setminRequiredCount] = useState(); const [sendInOrder, setSendInOrder] = useState(false); const [currWidgetsDetails, setCurrWidgetsDetails] = useState({}); - const [isSubscribed, setIsSubscribed] = useState(false); + const [isSubscriptionExpired, setIsSubscriptionExpired] = useState(false); const [extUserId, setExtUserId] = useState(""); const divRef = useRef(null); const isMobile = window.innerWidth < 767; @@ -137,23 +138,24 @@ function PdfRequestFiles() { async function checkIsSubscribed() { const res = await fetchSubscription(); - const freeplan = res.plan; + const plan = res.plan; const billingDate = res.billingDate; - if (freeplan === "freeplan") { + if (plan === "freeplan") { return true; } else if (billingDate) { if (new Date(billingDate) > new Date()) { + setIsSubscribed(true); return true; } else { if (location.pathname.includes("/load/")) { - setIsSubscribed(true); + setIsSubscriptionExpired(true); } else { navigate(`/subscription`); } } } else { if (location.pathname.includes("/load/")) { - setIsSubscribed(true); + setIsSubscriptionExpired(true); } else { navigate(`/subscription`); } @@ -977,10 +979,10 @@ function PdfRequestFiles() { return ( - {isSubscribed ? ( + {isSubscriptionExpired ? ( <ModalUi title={"Subscription Expired"} - isOpen={isSubscribed} + isOpen={isSubscriptionExpired} showClose={false} > <div className="flex flex-col justify-center items-center py-4 md:py-5 gap-5"> diff --git a/apps/OpenSign/src/pages/Report.js b/apps/OpenSign/src/pages/Report.js index 7d2d0fac1..9efd54329 100644 --- a/apps/OpenSign/src/pages/Report.js +++ b/apps/OpenSign/src/pages/Report.js @@ -56,39 +56,6 @@ const Report = () => { // setIsLoader(true); const json = reportJson(id); if (json) { - if (id === "6TeaPr321t") { - const tourConfig = [ - { - selector: "[data-tut=reactourFirst]", - content: () => ( - <TourContentWithBtn - message={ - "Click the ‘Add’ button to create a new template. Templates are reusable documents designed to quickly generate new documents with the same structure and varying signers. For example, an HR template for onboarding could have predefined roles like ‘HR Manager’ and ‘New Employee’. Each time you use the template, you can assign the ‘New Employee’ role to different incoming staff members, while the ‘HR Manager’ role remains constant, facilitating a seamless onboarding process for each recruit." - } - isChecked={handleDontShow} - /> - ), - position: "top", - style: { fontSize: "13px" } - } - ]; - json.actions.map((data) => { - const newConfig = { - selector: `[data-tut="${data?.selector}"]`, - content: () => ( - <TourContentWithBtn - message={data?.message} - isChecked={handleDontShow} - /> - ), - position: "top", - style: { fontSize: "13px" } - }; - tourConfig.push(newConfig); - }); - setTourData(tourConfig); - } - setActions(json.actions); setHeading(json.heading); setReportName(json.reportName); @@ -108,6 +75,42 @@ const Report = () => { headers: headers, signal: abortController.signal // is used to cancel fetch query }); + if (id === "6TeaPr321t") { + const tourConfig = [ + { + selector: "[data-tut=reactourFirst]", + content: () => ( + <TourContentWithBtn + message={ + "Click the 'Add' button to create a new template. Templates are reusable documents designed to quickly generate new documents with the same structure and varying signers. For example, an HR template for onboarding could have predefined roles like ‘HR Manager’ and ‘New Employee’. Each time you use the template, you can assign the ‘New Employee’ role to different incoming staff members, while the ‘HR Manager’ role remains constant, facilitating a seamless onboarding process for each recruit. " + } + isChecked={handleDontShow} + /> + ), + position: "top", + style: { fontSize: "13px" } + } + ]; + + if (res.data.result && res.data.result?.length > 0) { + json.actions.map((data) => { + const newConfig = { + selector: `[data-tut="${data?.selector}"]`, + content: () => ( + <TourContentWithBtn + message={data?.message} + isChecked={handleDontShow} + /> + ), + position: "top", + style: { fontSize: "13px" } + }; + tourConfig.push(newConfig); + }); + } + + setTourData(tourConfig); + } if (id === "4Hhwbp482K") { const listData = res.data?.result.filter((x) => x.Signers.length > 0); let arr = []; diff --git a/apps/OpenSign/src/primitives/GetReportDisplay.js b/apps/OpenSign/src/primitives/GetReportDisplay.js index 4684b3058..6ee660f27 100644 --- a/apps/OpenSign/src/primitives/GetReportDisplay.js +++ b/apps/OpenSign/src/primitives/GetReportDisplay.js @@ -8,6 +8,8 @@ import { modalSubmitBtnColor, modalCancelBtnColor } from "../constant/const"; import Alert from "./Alert"; import Tooltip from "./Tooltip"; import { RWebShare } from "react-web-share"; +import Tour from "reactour"; +import Parse from "parse"; const ReportTable = (props) => { const navigate = useNavigate(); @@ -23,6 +25,8 @@ const ReportTable = (props) => { const [copied, setCopied] = useState(false); const [isOption, setIsOption] = useState({}); const [alertMsg, setAlertMsg] = useState({ type: "success", message: "" }); + const [isTour, setIsTour] = useState(false); + const [tourStatusArr, setTourStatusArr] = useState([]); const startIndex = (currentPage - 1) * props.docPerPage; const { isMoreDocs, setIsNextRecord } = props; // For loop is used to calculate page numbers visible below table @@ -36,6 +40,7 @@ const ReportTable = (props) => { }, [props.List, props.docPerPage]); // below useEffect reset currenpage to 1 if user change route useEffect(() => { + checkTourStatus(); return () => setCurrentPage(1); }, []); @@ -346,6 +351,75 @@ const ReportTable = (props) => { setActLoader({}); }); }; + + async function checkTourStatus() { + const currentUser = Parse.User.current(); + const cloudRes = await Parse.Cloud.run("getUserDetails", { + email: currentUser.get("email") + }); + const res = { data: cloudRes.toJSON() }; + if (res.data && res.data.TourStatus && res.data.TourStatus.length > 0) { + const tourStatus = res.data.TourStatus; + // console.log("res ", res.data.TourStatus); + setTourStatusArr(tourStatus); + const filteredtourStatus = tourStatus.filter( + (obj) => obj["templateTour"] + ); + if (filteredtourStatus.length > 0) { + const templateTour = filteredtourStatus[0]["templateTour"]; + + if (templateTour) { + setIsTour(false); + } else { + setIsTour(true); + } + } else { + setIsTour(true); + } + } else { + setIsTour(true); + } + } + + const closeTour = async () => { + // console.log("closeTour"); + setIsTour(false); + if (props.isDontShow) { + const serverUrl = localStorage.getItem("baseUrl"); + const appId = localStorage.getItem("parseAppId"); + const extUserClass = localStorage.getItem("extended_class"); + const json = JSON.parse(localStorage.getItem("Extand_Class")); + const extUserId = json && json.length > 0 && json[0].objectId; + // console.log("extUserId ", extUserId) + + let updatedTourStatus = []; + if (tourStatusArr.length > 0) { + updatedTourStatus = [...tourStatusArr]; + const templateTourIndex = tourStatusArr.findIndex( + (obj) => obj["templateTour"] === false || obj["templateTour"] === true + ); + if (templateTourIndex !== -1) { + updatedTourStatus[templateTourIndex] = { templateTour: true }; + } else { + updatedTourStatus.push({ templateTour: true }); + } + } else { + updatedTourStatus = [{ templateTour: true }]; + } + + await axios.put( + serverUrl + "classes/" + extUserClass + "/" + extUserId, + { + TourStatus: updatedTourStatus + }, + { + headers: { + "X-Parse-Application-Id": appId + } + } + ); + } + }; return ( <div className="relative"> {Object.keys(actLoader)?.length > 0 && ( @@ -358,6 +432,15 @@ const ReportTable = (props) => { )} <div className="p-2 overflow-x-scroll w-full bg-white rounded-md"> {isAlert && <Alert type={alertMsg.type}>{alertMsg.message}</Alert>} + {props.tourData && props.ReportName === "Templates" && ( + <Tour + onRequestClose={closeTour} + steps={props.tourData} + isOpen={isTour} + // rounded={5} + closeWithMask={false} + /> + )} <div className="flex flex-row items-center justify-between my-2 mx-3 text-[20px] md:text-[23px]"> <div className="font-light"> {props.ReportName}{" "} @@ -369,6 +452,7 @@ const ReportTable = (props) => { </div> {props.ReportName === "Templates" && ( <i + data-tut="reactourFirst" onClick={() => navigate("/form/template")} className="fa-solid fa-square-plus text-sky-400 text-[25px]" ></i> @@ -500,6 +584,7 @@ const ReportTable = (props) => { {props.actions?.length > 0 && props.actions.map((act, index) => ( <button + data-tut={act?.selector} key={index} onClick={() => handleActionBtn(act, item)} className={`${