feat: implement daisy ui in dashboard

This commit is contained in:
prafull-opensignlabs
2024-06-05 20:23:50 +05:30
parent 5536c99052
commit c8801846fa
8 changed files with 275 additions and 150 deletions
@@ -26,18 +26,18 @@ const DashboardButton = (props) => {
props.Data && props.Data.Redirect_type
? "cursor-pointer"
: "cursor-default"
} w-full px-3 py-2 flex text-white rounded-md shadow overflow-hidden`}
} w-full shadow-md px-3 py-2 opcard bg-base-100`}
>
<div className="flex items-center justify-start gap-5">
<span className="rounded-full bg-black bg-opacity-20 w-[60px] h-[60px] self-start flex justify-center items-center">
<div className="flex flex-row items-center">
<span className="rounded-full bg-base-content bg-opacity-20 w-[60px] h-[60px] self-start flex justify-center items-center">
<i
className={`${
props.Icon ? props.Icon : "fa fa-solid fa-info"
} text-[25px] lg:text-[30px]`}
></i>
</span>
<div className="">
<div className="text-base lg:text-lg text-black"> {props.Label}</div>
<div className="opcard-title text-lg ml-3 text-base-content">
{props.Label}
</div>
</div>
</div>
@@ -336,9 +336,9 @@ const DashboardCard = (props) => {
props.Data && props.Data.Redirect_type
? "cursor-pointer"
: "cursor-default"
} w-full h-[140px] px-3 pt-4 pb-10 text-white rounded-md shadow overflow-hidden relative`}
}`}
>
<div className="flex items-center justify-start gap-5">
<div className="flex items-center justify-start gap-5 text-white">
<span className="rounded-full bg-black bg-opacity-20 w-[60px] h-[60px] self-start flex justify-center items-center">
<i
className={`${
@@ -346,15 +346,19 @@ const DashboardCard = (props) => {
} text-[25px] lg:text-[30px]`}
></i>
</span>
<div className="">
<div className=" font-medium">
<div className="text-base lg:text-lg"> {props.Label}</div>
<div className="text-2xl font-light">
{loading ? <div className="loader-01"></div> : setFormat(response)}
</div>
</div>
</div>
<div className="text-xs absolute top-2 right-1">
<Tooltip id={props.Label} iconColor={"white"} message={props?.Data?.tourMessage} />
<div className="text-xs absolute top-3 right-2">
<Tooltip
id={props.Label}
iconColor={"white"}
message={props?.Data?.tourMessage}
/>
</div>
</div>
);
@@ -121,19 +121,9 @@ function DashboardReport(props) {
return (
<>
{isLoader ? (
<div
style={{
height: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "center"
}}
>
<div className="h-[250px] flex justify-center items-center">
<div
style={{
fontSize: "45px",
color: "#3dd3e0"
}}
style={{ fontSize: "45px", color: "#3dd3e0" }}
className="loader-37"
></div>
</div>
@@ -18,7 +18,7 @@ const buttonList = [
];
const GetDashboard = (props) => {
const Button = ({ label, redirectId, redirectType, icon }) => (
<div className={"bg-white rounded-md shadow w-full"}>
<>
<Suspense
fallback={
<div style={{ height: "300px" }}>
@@ -40,14 +40,14 @@ const GetDashboard = (props) => {
Data={{ Redirect_type: redirectType, Redirect_id: redirectId }}
/>
</Suspense>
</div>
</>
);
const renderSwitchWithTour = (col) => {
switch (col.widget.type) {
case "Card":
return (
<div
className={"bg-[#2ed8b6] rounded-md shadow mb-3 md:mb-0"}
className="opcard bg-[#2ed8b6] w-full h-[140px] px-3 pt-4 mb-3 shadow-md"
data-tut={col.widget.data.tourSection}
style={{ background: col.widget.bgColor }}
>
@@ -89,7 +89,7 @@ const GetDashboard = (props) => {
);
}
default:
return null;
return <></>;
}
};
const renderSwitch = (col) => {
@@ -97,7 +97,7 @@ const GetDashboard = (props) => {
case "Card":
return (
<div
className={"bg-[#2ed8b6] rounded-md shadow mb-3 md:mb-0"}
className="opcard bg-[#2ed8b6] w-full h-[140px] px-3 pt-4 mb-3 shadow-md"
style={{ background: col.widget.bgColor }}
>
<Suspense fallback={<div>please wait</div>}>
@@ -122,7 +122,7 @@ const GetDashboard = (props) => {
);
}
default:
return null;
return <></>;
}
};
return (
@@ -130,7 +130,7 @@ const GetDashboard = (props) => {
<div className="mb-3">
<div
data-tut={"tourbutton"}
className="flex flex-col md:flex-row gap-6 md:gap-8"
className="flex flex-col md:flex-row gap-4"
>
{buttonList.map((btn) => (
<Button
@@ -143,21 +143,33 @@ const GetDashboard = (props) => {
))}
</div>
</div>
{props.dashboard.map((val, key) => (
<div key={"a" + key} className="row">
{val.columns.map((col, i) =>
col.widget.data && col.widget.data.tourSection ? (
<div key={i} className={props.classnameArray[key][i]}>
{renderSwitchWithTour(col)}
</div>
) : (
<div key={i} className={props.classnameArray[key][i]}>
{renderSwitch(col)}
</div>
)
)}
</div>
))}
<div className="grid grid-cols-12 w-full gap-x-4">
{props?.dashboard?.columns?.map((col, i) =>
col.widget.data && col.widget.data.tourSection ? (
<div
key={i}
className={`${
props?.classnameArray?.[i]
? props?.classnameArray[i]
: "col-span-12"
}`}
>
{renderSwitchWithTour(col)}
</div>
) : (
<div
key={i}
className={`${
props?.classnameArray?.[i]
? props?.classnameArray[i]
: "col-span-12"
}`}
>
{renderSwitch(col)}
</div>
)
)}
</div>
</div>
);
};
@@ -56,8 +56,12 @@ const Sidebar = ({ isOpen, closeSidebar }) => {
/>
</div>
<div>
<p className="text-[14px] font-bold">{username}</p>
<p className={`text-[12px] ${tenantname ? "mt-2" : ""}`}>
<p className="text-[14px] font-bold text-base-content">{username}</p>
<p
className={`text-[12px] text-base-content ${
tenantname ? "mt-2" : ""
}`}
>
{tenantname}
</p>
</div>
+100
View File
@@ -0,0 +1,100 @@
const dashboardJson = [
{
id: "35KBoSgoAK",
columns: [
{
colxs: "12",
colmd: "6",
collg: "6",
widget: {
type: "Card",
icon: "fas fa-signature",
bgColor: "#f0058e",
label: "Need your Signature",
description: null,
data: {
id: "e04ee9dc-932d-6b80-0202-703fd154eb74",
queryType: "",
class: "contracts_Document",
query:
'where={"$and":[{"AuditTrail.UserPtr":{"$ne":{"__type":"Pointer","className": "contracts_Users","objectId":"#objectId#"}}},{"AuditTrail.Activity":{"$ne":"Signed"}}],"Signers":{"$in":[{"__type":"Pointer","className":"contracts_Users","objectId":"#objectId#"}]},"IsDeclined":{"$ne":true},"IsCompleted":{"$ne":true},"Type":{"$ne":"Folder"},"Placeholders":{"$ne":null},"ExpiryDate":{"#*gt":{"__type":"#Date#","iso":"#today#"}}}&count=1',
key: "count",
Redirect_type: "Report",
Redirect_id: "4Hhwbp482K",
tourSection: "tourcard1",
tourMessage:
"Clicking on this card will take you to the list of documents awaiting your review."
}
}
},
{
colxs: "12",
colmd: "6",
collg: "6",
widget: {
type: "Card",
icon: "fas fa-sign-out-alt",
bgColor: "#g0058e",
label: "Out for signatures",
description: null,
data: {
id: "c1935cc0-28d4-3d73-b72a-8c1e3d18a17f",
queryType: "",
class: "contracts_Document",
query:
'where={"Type":{"#*ne":"Folder"},"Signers":{"#*exists":true,"#*ne":[]},"Placeholders":{"#*ne":null},"IsCompleted":{"#*ne":true},"IsDeclined":{"#*ne":true},"IsArchive":{"#*ne":true},"CreatedBy":{"__type":"Pointer","className":"_User","objectId":"#UserId.objectId#"},"ExpiryDate":{"#*gt":{"__type":"#Date#","iso":"#today#"}}}&count=1',
key: "count",
Redirect_type: "Report",
Redirect_id: "1MwEuxLEkF",
tourSection: "tourcard2",
tourMessage:
"Clicking on this card will take you to a list of documents awaiting signature."
}
}
},
{
colxs: "12",
colmd: "6",
collg: "6",
widget: {
type: "report",
reportId: "5Go51Q7T8r",
data: {
tourSection: "tourreport1",
tourMessage:
"This is a list of documents that are waiting for your signature."
}
}
},
{
colxs: "12",
colmd: "6",
collg: "6",
widget: {
type: "report",
reportId: "d9k3UfYHBc",
data: {
tourSection: "tourreport2",
tourMessage:
"This is a list of documents you've sent to other parties for signature."
}
}
},
{
colxs: "12",
colmd: "12",
collg: "12",
widget: {
type: "report",
reportId: "kC5mfynCi4",
data: {
tourSection: "tourreport3",
tourMessage:
"This are documents you have started but have not finalized for sending."
}
}
}
]
}
];
export default dashboardJson;
+39 -72
View File
@@ -1,11 +1,11 @@
import React, { useState, useEffect } from "react";
import Parse from "parse";
import "../styles/loader.css";
import GetDashboard from "../components/dashboard/GetDashboard";
import { useNavigate, useParams } from "react-router-dom";
import Title from "../components/Title";
import { useDispatch } from "react-redux";
import { saveTourSteps } from "../redux/reducers/TourStepsReducer";
import dashboardJson from "../json/dashboardJson";
const Dashboard = () => {
const navigate = useNavigate();
@@ -13,7 +13,7 @@ const Dashboard = () => {
const { id } = useParams();
const [dashboard, setdashboard] = useState([]);
const [classnameArray, setclassnameArray] = useState([]);
const [loading, setloading] = useState(false);
const [loading, setloading] = useState(true);
const [defaultQuery, setDefaultQuery] = useState("");
useEffect(() => {
@@ -30,53 +30,27 @@ const Dashboard = () => {
}, [id]);
const getDashboard = async (id) => {
setloading(true);
try {
var forms = Parse.Object.extend("w_dashboard");
var query = new Parse.Query(forms);
query.equalTo("objectId", id);
const results = await query.first();
const resultjson = results.toJSON();
const dashboard = dashboardJson.find((x) => x.id === id);
let classArray = [];
let DefaultQuery = "";
resultjson.rows.forEach((x) => {
let col_lg = "",
col_md = "",
col_xs = "",
col_sm = "",
col_ = "",
obj = {};
let subItem = [];
dashboard?.columns?.forEach((row) => {
let item = "";
x.columns.forEach((y) => {
if (y.widget.type === "customeHtml") {
DefaultQuery = y.widget.data[0].default;
}
if (Number(y["collg"]) > 0) {
col_lg = "col-lg-" + y["collg"];
}
if (Number(y["colmd"]) > 0) {
col_md = "col-md-" + y["colmd"];
}
if (Number(y["colxs"]) > 0) {
col_xs = "col-xs-" + y["colxs"];
}
if (Number(y["colsm"]) > 0) {
col_sm = "col-sm-" + y["colsm"];
}
if (Number(y["col"]) > 0) {
col_ = "col-" + y["col"];
}
item =
col_lg + " " + col_md + " " + col_xs + " " + col_sm + " " + col_;
subItem.push(item);
});
obj = subItem;
classArray.push(obj);
if (row?.colxs) {
item += " col-span-" + row?.colxs;
}
if (row?.colmd) {
item += " md:col-span-" + row?.colmd;
}
if (row?.collg) {
item += " lg:col-span-" + row?.collg + " ";
}
if (!row?.colxs && !row?.colmd && !row?.collg) {
item += "col-span-12";
}
classArray.push(item);
});
setdashboard(resultjson.rows);
// console.log("resultjson.rows ", resultjson.rows);
const arr = resultjson.rows[0].columns
setdashboard(dashboard);
const dashboardTour = dashboard.columns
.filter((col) => {
if (col.widget.data && col.widget.data.tourSection) {
return col;
@@ -90,13 +64,10 @@ const Dashboard = () => {
// style: { backgroundColor: "#abd4d2" },
};
});
dispatch(saveTourSteps(arr));
// console.log("arr ", arr);
dispatch(saveTourSteps(dashboardTour));
setclassnameArray(classArray);
if (localStorage.getItem("DashboardDefaultFilter")) {
setDefaultQuery(localStorage.getItem("DashboardDefaultFilter"));
} else {
setDefaultQuery(DefaultQuery);
}
setloading(false);
} catch (e) {
@@ -105,32 +76,28 @@ const Dashboard = () => {
}
};
let _dash = (
<GetDashboard
dashboard={dashboard}
classnameArray={classnameArray}
DefaultQuery={defaultQuery}
/>
);
if (loading) {
_dash = (
<div style={{ height: "300px", backgroundColor: "white" }}>
<div
style={{
marginLeft: "45%",
marginTop: "150px",
fontSize: "45px",
color: "#3dd3e0"
}}
className="loader-37"
></div>
</div>
);
}
return (
<React.Fragment>
<Title title="Dashboard" />
{_dash}
{loading ? (
<div style={{ height: "300px", backgroundColor: "white" }}>
<div
style={{
marginLeft: "45%",
marginTop: "150px",
fontSize: "45px",
color: "#3dd3e0"
}}
className="loader-37"
></div>
</div>
) : (
<GetDashboard
dashboard={dashboard}
classnameArray={classnameArray}
DefaultQuery={defaultQuery}
/>
)}
</React.Fragment>
);
};
@@ -1,4 +1,4 @@
import React, { useState, useEffect, useMemo } from "react";
import React, { useState, useEffect } from "react";
import pad from "../assets/images/pad.svg";
import { useNavigate } from "react-router-dom";
import axios from "axios";
@@ -60,13 +60,65 @@ const ReportTable = (props) => {
const { isMoreDocs, setIsNextRecord } = props;
// For loop is used to calculate page numbers visible below table
// Initialize pageNumbers using useMemo to avoid unnecessary re-creation
const pageNumbers = useMemo(() => {
const calculatedPageNumbers = [];
for (let i = 1; i <= Math.ceil(props.List.length / props.docPerPage); i++) {
calculatedPageNumbers.push(i);
// const pageNumbers = useMemo(() => {
// const calculatedPageNumbers = [];
// for (let i = 1; i <= Math.ceil(props.List.length / props.docPerPage); i++) {
// calculatedPageNumbers.push(i);
// }
// return calculatedPageNumbers;
// }, [props.List, props.docPerPage]);
const getPaginationRange = () => {
const totalPageNumbers = 7; // Adjust this value to show more/less page numbers
const pages = [];
const totalPages = Math.ceil(props.List.length / props.docPerPage);
if (totalPages <= totalPageNumbers) {
for (let i = 1; i <= totalPages; i++) {
pages.push(i);
}
} else {
const leftSiblingIndex = Math.max(currentPage - 1, 1);
const rightSiblingIndex = Math.min(currentPage + 1, totalPages);
const showLeftDots = leftSiblingIndex > 2;
const showRightDots = rightSiblingIndex < totalPages - 2;
const firstPageIndex = 1;
const lastPageIndex = totalPages;
if (!showLeftDots && showRightDots) {
let leftItemCount = 3;
let leftRange = Array.from({ length: leftItemCount }, (_, i) => i + 1);
pages.push(...leftRange);
pages.push("...");
pages.push(totalPages);
} else if (showLeftDots && !showRightDots) {
let rightItemCount = 3;
let rightRange = Array.from(
{ length: rightItemCount },
(_, i) => totalPages - rightItemCount + i + 1
);
pages.push(firstPageIndex);
pages.push("...");
pages.push(...rightRange);
} else if (showLeftDots && showRightDots) {
let middleRange = Array.from(
{ length: 3 },
(_, i) => leftSiblingIndex + i
);
pages.push(firstPageIndex);
pages.push("...");
pages.push(...middleRange);
pages.push("...");
pages.push(lastPageIndex);
}
}
return calculatedPageNumbers;
}, [props.List, props.docPerPage]);
return pages;
};
const pageNumbers = getPaginationRange();
// below useEffect reset currenpage to 1 if user change route
useEffect(() => {
checkTourStatus();
@@ -839,7 +891,7 @@ const ReportTable = (props) => {
></div>
</div>
)}
<div className="p-2 overflow-x-scroll w-full bg-white rounded-md">
<div className="p-2 overflow-x-scroll w-full bg-white rounded-xl">
{isCelebration && (
<div style={{ position: "relative", zIndex: "1000" }}>
<Confetti width={window.innerWidth} height={window.innerHeight} />
@@ -1509,46 +1561,42 @@ const ReportTable = (props) => {
)}
</tbody>
</table>
<div className="flex flex-wrap items-center gap-2 p-2 ">
<div className="opjoin flex flex-wrap items-center p-2 ">
{props.List.length > props.docPerPage && (
<>
{currentPage > 1 && (
<button
onClick={() => paginateBack()}
className="bg-blue-400 text-white rounded px-3 py-2 focus:outline-none"
>
Prev
</button>
)}
<button
onClick={() => paginateBack()}
className="opjoin-item opbtn "
>
Prev
</button>
</>
)}
{pageNumbers.map((x) => (
{pageNumbers.map((x, i) => (
<button
key={x}
key={i}
onClick={() => setCurrentPage(x)}
className=" bg-sky-400 text-white rounded px-3 py-2 focus:outline-none"
disabled={x === "..."}
className={`${
x === currentPage ? "opbtn-active" : ""
} opjoin-item opbtn`}
>
{x}
</button>
))}
{isMoreDocs && (
<button className="text-black rounded px-1 py-2">...</button>
)}
{props.List.length > props.docPerPage && (
<>
{pageNumbers.includes(currentPage + 1) && (
<button
onClick={() => paginateFront()}
className="bg-blue-400 text-white rounded px-3 py-2 focus:outline-none"
>
Next
</button>
)}
<button
onClick={() => paginateFront()}
className="opjoin-item opbtn"
>
Next
</button>
</>
)}
</div>
{props.List?.length <= 0 && (
<div className="flex flex-col items-center justify-center w-full bg-white rounded py-4">
<div className="flex flex-col items-center justify-center w-full bg-white rounded-xl py-4">
<div className="w-[60px] h-[60px] overflow-hidden">
<img
className="w-full h-full object-contain"