mirror of
https://github.com/OpenSignLabs/OpenSign.git
synced 2026-08-30 19:59:49 +02:00
feat: implement daisy ui in dashboard
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user