feat : add tour message on template report and opensign-drive

This commit is contained in:
RaktimaNXG
2024-04-10 15:57:05 +05:30
parent 2f3cdca821
commit 05fe68d458
7 changed files with 378 additions and 37 deletions
@@ -385,6 +385,7 @@ function DriveBody(props) {
flexDirection: "column",
cursor: "pointer"
}}
data-tut={props.dataTutSeventh}
>
<img
alt="no img"
@@ -452,6 +453,7 @@ function DriveBody(props) {
className="pdf-icon"
src={pdfLogo}
onClick={() => checkPdfStatus(data)}
data-tut={props.dataTutSixth}
/>
{rename === data.objectId ? (
<input
+17 -7
View File
@@ -19,7 +19,8 @@ export default function reportJson(id) {
redirectUrl: "draftDocument"
}
],
helpMsg: "These are documents you have started but have not finalized for sending."
helpMsg:
"These are documents you have started but have not finalized for sending."
};
// Need your sign report
case "4Hhwbp482K":
@@ -69,7 +70,8 @@ export default function reportJson(id) {
redirectUrl: "draftDocument"
}
],
helpMsg: "This is a list of documents that have been signed by all parties."
helpMsg:
"This is a list of documents that have been signed by all parties."
};
// declined documents report
case "UPr2Fm5WY3":
@@ -85,7 +87,8 @@ export default function reportJson(id) {
redirectUrl: "draftDocument"
}
],
helpMsg: "This is a list of documents that have been declined by one of the signers."
helpMsg:
"This is a list of documents that have been declined by one of the signers."
};
// Expired Documents report
case "zNqBHXHsYH":
@@ -101,7 +104,8 @@ export default function reportJson(id) {
redirectUrl: "draftDocument"
}
],
helpMsg: "This is a list of documents that have reached their expiration date."
helpMsg:
"This is a list of documents that have reached their expiration date."
};
// Recently sent for signatures report show on dashboard
case "d9k3UfYHBc":
@@ -162,7 +166,8 @@ export default function reportJson(id) {
}
],
form: "ContactBook",
helpMsg: "This is a list of contacts/signers added by you. These will appear as suggestions when you try to add signers to a new document."
helpMsg:
"This is a list of contacts/signers added by you. These will appear as suggestions when you try to add signers to a new document."
};
// template report
case "6TeaPr321t":
@@ -175,16 +180,21 @@ export default function reportJson(id) {
btnColor: "#4bd396",
textColor: "white",
btnIcon: "fa fa-plus",
redirectUrl: "placeHolderSign"
redirectUrl: "placeHolderSign",
selector: "reactourSecond",
message: "onclick use button to create document from template."
},
{
btnLabel: "Edit",
btnColor: "#00c9d5",
textColor: "white",
btnIcon: "fa fa-plus",
redirectUrl: "template"
redirectUrl: "template",
selector: "reactourThird",
message: "onclick edit button you can edit template."
}
],
helpMsg:
"This is a list of templates that are available to you for creating documents. You can click the 'use' button to create a new document using a template, modify the document & add signers in the next step."
};
+7 -5
View File
@@ -1072,11 +1072,13 @@ function Login() {
<div aria-labelledby="loginHeading" role="region">
<div className="md:m-10 lg:m-16 md:p-4 lg:p-10 p-4 bg-[#ffffff] md:border-[1px] md:border-gray-400 ">
<div className="w-[250px] h-[66px] inline-block overflow-hidden">
<img
src={image}
className="object-contain h-full"
alt="The image displays the OpenSign logo with a stylized blue square with an open corner, accompanied by the tagline Seal the Deal, Openly."
/>
{image && (
<img
src={image}
className="object-contain h-full"
alt="The image displays the OpenSign logo with a stylized blue square with an open corner, accompanied by the tagline Seal the Deal, Openly."
/>
)}
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
<div>
+221 -21
View File
@@ -7,6 +7,10 @@ import { useNavigate } from "react-router-dom";
import Title from "../components/Title";
import Parse from "parse";
import ModalUi from "../primitives/ModalUi";
import TourContentWithBtn from "../primitives/TourContentWithBtn";
import Tour from "reactour";
import axios from "axios";
const DriveBody = React.lazy(
() => import("../components/opensigndrive/DriveBody")
);
@@ -42,6 +46,8 @@ function Opensigndrive() {
const [error, setError] = useState();
const [folderLoader, setIsFolderLoader] = useState(false);
const [isShowSort, setIsShowSort] = useState(false);
const [isTour, setIsTour] = useState(false);
const [tourStatusArr, setTourStatusArr] = useState([]);
const [isLoading, setIsLoading] = useState({
isLoad: true,
message: "This might take some time"
@@ -56,6 +62,8 @@ function Opensigndrive() {
const [loading, setLoading] = useState(false);
const sortOrder = ["Ascending", "Descending"];
const sortingValue = ["Name", "Date"];
const [isDontShow, setIsDontShow] = useState(false);
const [tourData, setTourData] = useState();
const orderName = {
Ascending: "Ascending",
Descending: "Descending",
@@ -73,12 +81,98 @@ function Opensigndrive() {
useEffect(() => {
getPdfDocumentList();
// eslint-disable-next-line
}, [docId]);
const tourConfigs = [
{
selector: '[data-tut="reactourFirst"]',
content: () => (
<TourContentWithBtn
message={`click on folder path you can re-redirect to see of that folder list of document.`}
isChecked={handleDontShow}
/>
),
position: "top",
style: { fontSize: "13px" }
},
{
selector: '[data-tut="reactourSecond"]',
content: () => (
<TourContentWithBtn
message={`click on add button you can see option of to create new folder and create new document.`}
isChecked={handleDontShow}
/>
),
position: "top",
style: { fontSize: "13px" }
},
{
selector: '[data-tut="reactourThird"]',
content: () => (
<TourContentWithBtn
message={`you can sort your document list using Date or Name.`}
isChecked={handleDontShow}
/>
),
position: "top",
style: { fontSize: "13px" }
},
{
selector: '[data-tut="reactourForth"]',
content: () => (
<TourContentWithBtn
message={`click on this menu you can change document list in table format.`}
isChecked={handleDontShow}
/>
),
position: "top",
style: { fontSize: "13px" }
},
{
selector: '[data-tut="reactourFifth"]',
content: () => (
<TourContentWithBtn
message={`this document list is render according to selected sort and icon show document status.`}
isChecked={handleDontShow}
/>
),
position: "bottom",
style: { fontSize: "13px" }
},
{
selector: '[data-tut="reactourSixth"]',
content: () => (
<TourContentWithBtn
message={`on right click on document you can see four option (Download,Rename,Move,Delete) and onclick on document
you can navigate next page to see status of document
.`}
isChecked={handleDontShow}
/>
),
position: "bottom",
style: { fontSize: "13px" }
},
{
selector: '[data-tut="reactourSeventh"]',
content: () => (
<TourContentWithBtn
message={`on right click on folder you can see option (Rename) and onclick on folder
you can navigate next page to see document list exist in that folder
.`}
isChecked={handleDontShow}
/>
),
position: "bottom",
style: { fontSize: "13px" }
}
];
//function for get all pdf document list
const getPdfDocumentList = async (disbaleLoading) => {
setLoading(true);
checkTourStatus();
if (!disbaleLoading) {
setIsLoading({ isLoad: true, message: "This might take some time" });
}
@@ -87,6 +181,22 @@ function Opensigndrive() {
if (driveDetails && driveDetails === "Error: Something went wrong!") {
setHandleError("Error: Something went wrong!");
} else if (driveDetails && driveDetails.length > 0) {
let newTour = tourConfigs;
const isFolderExist = driveDetails.some(
(data) => data.Type === "Folder"
);
if (!isFolderExist) {
newTour = newTour.filter(
(data) => data.selector !== '[data-tut="reactourSeventh"]'
);
}
const isDocumentExist = driveDetails.some((data) => data.URL);
if (!isDocumentExist) {
newTour = newTour.filter(
(data) => data.selector !== '[data-tut="reactourSixth"]'
);
}
setTourData(newTour);
setSkip((prevSkip) => prevSkip + limit);
sortingData(null, null, driveDetails, true);
}
@@ -358,9 +468,78 @@ function Opensigndrive() {
setNewFolderName("");
setError("");
};
const handleDontShow = (isChecked) => {
setIsDontShow(isChecked);
};
const closeTour = async () => {
setIsTour(false);
if (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;
let updatedTourStatus = [];
if (tourStatusArr.length > 0) {
updatedTourStatus = [...tourStatusArr];
const opensignTourIndex = tourStatusArr.findIndex(
(obj) => obj["opensignTour"] === false || obj["opensignTour"] === true
);
if (opensignTourIndex !== -1) {
updatedTourStatus[opensignTourIndex] = { opensignTour: true };
} else {
updatedTourStatus.push({ opensignTour: true });
}
} else {
updatedTourStatus = [{ opensignTour: true }];
}
await axios.put(
serverUrl + "classes/" + extUserClass + "/" + extUserId,
{
TourStatus: updatedTourStatus
},
{
headers: {
"X-Parse-Application-Id": appId
}
}
);
}
};
//function to use check tour status of open sign drive
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;
setTourStatusArr(tourStatus);
const filteredtourStatus = tourStatus.filter(
(obj) => obj["opensignTour"]
);
if (filteredtourStatus.length > 0) {
const opensignTour = filteredtourStatus[0]["opensignTour"];
// console.log("loginTour", loginTour);
if (opensignTour) {
setIsTour(false);
} else {
setIsTour(true);
}
} else {
setIsTour(true);
}
} else {
setIsTour(true);
}
}
return (
<div style={{ backgroundColor: "white" }} className="folderComponent">
<Title title={"OpenSign™ Drive"} drive={true} />
<div>
<ModalUi
headerColor={"#dc3545"}
@@ -523,7 +702,16 @@ function Opensigndrive() {
) : (
<>
<div className="folderContainer">
<Tour
onRequestClose={closeTour}
steps={tourData}
isOpen={isTour}
closeWithMask={false}
scrollOffset={-100}
rounded={5}
/>
<div
data-tut="reactourFirst"
onMouseEnter={(e) => handleMouseEnter(e)}
ref={scrollRef}
style={{
@@ -541,7 +729,7 @@ function Opensigndrive() {
}
onClick={() => setIsNewFol(!isNewFol)}
>
<div className="sort">
<div className="sort" data-tut="reactourSecond">
<i
className="fa fa-plus-square"
aria-hidden="true"
@@ -602,7 +790,11 @@ function Opensigndrive() {
className={isShowSort ? "dropdown show" : "dropdown"}
onClick={() => setIsShowSort(!isShowSort)}
>
<div className=" sort " data-toggle="dropdown">
<div
data-tut="reactourThird"
className=" sort "
data-toggle="dropdown"
>
<i
className="fa fa-sort-amount-asc"
aria-hidden="true"
@@ -692,7 +884,11 @@ function Opensigndrive() {
></i>
</div>
) : (
<div className="sort" onClick={() => setIsList(!isList)}>
<div
data-tut="reactourForth"
className="sort"
onClick={() => setIsList(!isList)}
>
<i
className="fa fa-list"
aria-hidden="true"
@@ -717,24 +913,28 @@ function Opensigndrive() {
<span style={{ fontWeight: "bold" }}>No Data Found!</span>
</div>
) : (
<React.Suspense fallback={<Loader />}>
<DriveBody
pdfData={pdfData}
setFolderName={setFolderName}
setIsLoading={setIsLoading}
setDocId={setDocId}
getPdfDocumentList={getPdfDocumentList}
isDocId={docId}
setPdfData={setPdfData}
isList={isList}
setIsAlert={setIsAlert}
setSkip={setSkip}
sortingData={sortingData}
/>
{loading && (
<div style={{ textAlign: "center" }}>Loading...</div>
)}
</React.Suspense>
<div data-tut="reactourFifth">
<React.Suspense fallback={<Loader />}>
<DriveBody
dataTutSixth="reactourSixth"
dataTutSeventh="reactourSeventh"
pdfData={pdfData}
setFolderName={setFolderName}
setIsLoading={setIsLoading}
setDocId={setDocId}
getPdfDocumentList={getPdfDocumentList}
isDocId={docId}
setPdfData={setPdfData}
isList={isList}
setIsAlert={setIsAlert}
setSkip={setSkip}
sortingData={sortingData}
/>
{loading && (
<div style={{ textAlign: "center" }}>Loading...</div>
)}
</React.Suspense>
</div>
)}
</>
)}
+39
View File
@@ -6,6 +6,7 @@ import reportJson from "../json/ReportJson";
import { useParams } from "react-router-dom";
import Title from "../components/Title";
import PageNotFound from "./PageNotFound";
import TourContentWithBtn from "../primitives/TourContentWithBtn";
const Report = () => {
const { id } = useParams();
@@ -18,6 +19,8 @@ const Report = () => {
const [isNextRecord, setIsNextRecord] = useState(false);
const [isMoreDocs, setIsMoreDocs] = useState(true);
const [form, setForm] = useState("");
const [tourData, setTourData] = useState([]);
const [isDontShow, setIsDontShow] = useState(false);
const abortController = new AbortController();
const docPerPage = 10;
@@ -46,10 +49,44 @@ const Report = () => {
// eslint-disable-next-line
}, [isNextRecord]);
const handleDontShow = (isChecked) => {
setIsDontShow(isChecked);
};
const getReportData = async (skipUserRecord = 0, limit = 200) => {
// setIsLoader(true);
const json = reportJson(id);
if (json) {
if (id === "6TeaPr321t") {
const tourConfig = [
{
selector: "[data-tut=reactourFirst]",
content: () => (
<TourContentWithBtn
message={`onclick add button you can create new template.`}
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);
@@ -161,6 +198,8 @@ const Report = () => {
docPerPage={docPerPage}
form={form}
report_help={reporthelp}
tourData={tourData}
isDontShow={isDontShow}
/>
) : (
<PageNotFound prefix={"Report"} />
+3 -1
View File
@@ -533,7 +533,9 @@ const Signup = () => {
<div>
<div className="md:m-10 lg:m-16 md:p-4 lg:p-10 p-5 bg-[#ffffff] md:border-[1px] md:border-gray-400 ">
<div className="w-[250px] h-[66px] inline-block overflow-hidden">
<img src={image} className="object-contain h-full" alt="logo" />
{image && (
<img src={image} className="object-contain h-full" alt="logo" />
)}
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-2">
<div className="">
@@ -3,10 +3,12 @@ import pad from "../assets/images/pad.svg";
import { useNavigate } from "react-router-dom";
import axios from "axios";
import ModalUi from "./ModalUi";
import Tour from "reactour";
import AddSigner from "../components/AddSigner";
import { modalSubmitBtnColor, modalCancelBtnColor } from "../constant/const";
import Alert from "./Alert";
import Tooltip from "./Tooltip";
import Parse from "parse";
const ReportTable = ({
ReportName,
List,
@@ -17,7 +19,9 @@ const ReportTable = ({
isMoreDocs,
docPerPage,
form,
report_help
report_help,
tourData,
isDontShow
}) => {
const navigate = useNavigate();
const [currentPage, setCurrentPage] = useState(1);
@@ -27,6 +31,8 @@ const ReportTable = ({
const [isDocErr, setIsDocErr] = useState(false);
const [isContactform, setIsContactform] = useState(false);
const [isDeleteModal, setIsDeleteModal] = useState({});
const [isTour, setIsTour] = useState(false);
const [tourStatusArr, setTourStatusArr] = useState([]);
const startIndex = (currentPage - 1) * docPerPage;
// For loop is used to calculate page numbers visible below table
@@ -40,6 +46,7 @@ const ReportTable = ({
}, [List, docPerPage]);
// below useEffect reset currenpage to 1 if user change route
useEffect(() => {
checkTourStatus();
return () => setCurrentPage(1);
}, []);
@@ -146,8 +153,6 @@ const ReportTable = ({
}
}
);
// console.log("Res ", res.data);
if (res.data && res.data.objectId) {
setActLoader({});
setIsAlert(true);
@@ -247,6 +252,74 @@ const ReportTable = ({
};
const handleCloseDeleteModal = () => setIsDeleteModal({});
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 (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="p-2 overflow-x-scroll w-full bg-white rounded-md">
{isAlert && (
@@ -256,6 +329,16 @@ const ReportTable = ({
: "Record deleted successfully!"}
</Alert>
)}
{tourData && ReportName === "Templates" && (
<Tour
onRequestClose={closeTour}
steps={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">
{ReportName}{" "}
@@ -267,6 +350,7 @@ const ReportTable = ({
</div>
{ReportName === "Templates" && (
<i
data-tut="reactourFirst"
onClick={() => navigate("/form/template")}
className="fa-solid fa-square-plus text-sky-400 text-[25px]"
></i>
@@ -280,6 +364,7 @@ const ReportTable = ({
</div>
)}
</div>
<table className="table-auto w-full border-collapse">
<thead className="text-[14px]">
<tr className="border-y-[1px]">
@@ -410,6 +495,7 @@ const ReportTable = ({
{actions?.length > 0 &&
actions.map((act, index) => (
<button
data-tut={act?.selector}
key={index}
onClick={() =>
act?.redirectUrl