I have a react parent component which is rendering a Table component which is react-data-table-component. The data is being fetched corrctly but there is pagination footer text problem. There are 26 data. First it is showing 1-10 of 26, then I click next pagination button, it is showing right data but again same 1-10 of 26 but when I click again its getting corrected to 11-20 of 26, but the API is not getting called because the data is correct.
this is the parent component
import React, { useEffect, useState } from "react";
import styles from "../../Components/Scss/Admin.module.scss";
import Table from "../../Components/Global/Table";
import { useAuth } from "../../Context/AuthContext";
import { useLocation, useNavigate } from "react-router-dom";
import Loader from "../../Components/Global/widget/Loader";
import axios from "axios";
import moment from "moment-timezone";
import CompanyLayout from "../../Components/Company/Layouts";
import Filters from "../../Components/Global/transaction/Filters";
import NoData from "../../Components/Global/widget/NoData";
import { toNumber } from "lodash";
import { HasPermission } from "../../Components/Global/Permission";
import Unauthorised from "../Global/Unauthorised";
import { currencyFormat } from "../../Utils/Common";
import download from "downloadjs";
export default function CustomerDetails({ permission }) {
const { userInfo, token, selectedStoreIds } = useAuth();
const [data, setData] = useState(true);
const [amount, setAmount] = useState();
const [tips, setTips] = useState();
const [refund, setRefund] = useState();
const [salesAmount, setSalesAmount] = useState();
const [salesPlusFees, setSalesPlusFees] = useState();
const [salesPlusTips, setSalesPlusTips] = useState();
const [noOfTransactions, setNoOfTransactions] = useState();
const [hiddenChart, setHiddenChart] = useState(true);
const [customer, setCustomer] = useState("");
const [allTransactionData, setAllTransactionData] = useState();
const [datePick, setDatePick] = useState();
const [to, setTo] = useState("");
const [from, setFrom] = useState("");
const [totalRows, setTotalRows] = useState();
const perPage = 10;
const [search, setSearch] = useState("");
const [currentStoreId, setCurrentStoreId] = useState(selectedStoreIds);
const [currentPage, setCurrentPage] = useState(1);
const [resApiData, setResApiData] = useState(false);
const [loading, setLoading] = useState(false);
const [tableLoading, setTableLoading] = useState(true);
const navigate = useNavigate();
const location = useLocation();
const getCustomerId = location.pathname.split("/").slice(-1);
const getTransactions = async () => {
let userType = "store";
setTableLoading(true);
const data = await axios.post(
`/customer/transctions/list/${getCustomerId}`,
{
s: search,
days: "",
from: from,
to: to,
size: perPage,
page: currentPage,
type: userType,
stores: currentStoreId,
},
{
headers: { Authorization: "Bearer " + token },
}
);
if (data && data.data && data.data.response && data.data.response.records) {
filterData(data.data.response);
setTotalRows(data.data.response.totalItems);
setTableLoading(false);
} else {
setTableLoading(false);
}
};
useEffect(() => {
//ref.current.continuousStart();
setCurrentStoreId(selectedStoreIds);
}, [selectedStoreIds]);
useEffect(() => {
if (token && currentStoreId) {
getTransactions();
let userType = "store";
setResApiData(false);
axios
.post(
`/customer/transctions/${getCustomerId}`,
{
type: userType,
from: from,
to: to,
s: search,
stores: currentStoreId,
},
{
headers: { Authorization: "Bearer " + token },
}
)
.then((response) => {
if (response.data.response) {
//ref.current.complete();
setData(false);
setResApiData(true);
const transactionsAmountCount = currencyFormat(
toNumber(response.data.response.metabox.total_order_amount)
);
const tipsAmountCount = currencyFormat(
toNumber(response.data.response.metabox.totaltips)
);
const refundAmountCount = currencyFormat(
toNumber(response.data.response.metabox.returns)
);
setNoOfTransactions(
response.data.response.metabox.noOfTransactions
);
setSalesAmount(
currencyFormat(response.data.response.metabox.salesAmount)
);
setSalesPlusFees(
currencyFormat(response.data.response.metabox.salesPlusFees)
);
setSalesPlusTips(
currencyFormat(response.data.response.metabox.salesPlusTips)
);
const getCustomerName = response.data.response.response.fullName;
setCustomer(getCustomerName);
setAmount(transactionsAmountCount);
setTips(tipsAmountCount);
setRefund(refundAmountCount);
if (transactionsAmountCount == 0) {
setData(false);
} else {
setData(true);
}
} else {
setData(false);
setResApiData(true);
}
})
.catch(() => {
setResApiData(true);
});
}
}, [token, datePick, search, currentStoreId, currentPage]);
const columns = [
{
name: "#",
selector: (row) => row.serialNo,
width: "50px",
},
{
name: "Date",
selector: (row) => row.date,
},
{
name: "Store Name",
selector: (row) => row.storeName,
wrap: true,
},
{
name: "Associate Name",
selector: (row) => row.associate,
wrap: true,
},
{
name: "Order Amount",
selector: (row) => row.orderAmount,
},
{
name: "Payment Type",
selector: (row) => row.paymentType,
wrap: true,
},
];
const filterData = (data) => {
let records = [];
data.records.map((items, index) => {
records.push({
serialNo: index + 1,
date: moment(items?.transaction.createdAt).format("ll"),
storeName: items?.transaction?.Store?.store_name,
associate:
items?.associate?.first_name + " " + items?.associate?.last_name,
orderAmount: currencyFormat(toNumber(items?.transaction?.order_amount)),
paymentType: items?.transaction?.payment_type,
external_id: items?.transaction?.transactions_external_id,
});
});
setAllTransactionData(records);
};
const handleSearchSubmit = async (val) => {
if (val) {
setSearch(val);
}
};
const handleDateChange = async (val) => {
setDatePick(val);
setFrom(moment(val[0]).startOf("day").format("YYYY-MM-DD hh:mm:ss:SSS"));
setTo(moment(val[1]).startOf("day").format("YYYY-MM-DD hh:mm:ss:SSS"));
};
const onRowClick = (val) => {
navigate(`/transaction/${val.external_id}`);
};
const handleOnPageChange = async (val) => {
if (val) {
setCurrentPage(val);
}
};
const quarries = {
stores: currentStoreId,
customer_external_id: getCustomerId,
from: from,
to: to,
};
const handleDownload = async () => {
try {
setLoading(true);
const data = await axios.post(
"/download/transaction/report/customer",
quarries,
{
responseType: "blob",
headers: { Authorization: "Bearer " + token },
}
);
setLoading(false);
download(
data.data,
`Customer transactions reports ${moment(new Date()).format(
"MMMM Do YYYY"
)}`
);
} catch (e) {
setLoading(false);
}
};
const HandelHiddenChart = (e) => {
const hiddenChartVal = e.target.checked;
setHiddenChart(hiddenChartVal);
};
return (
<>
{/*<LoadingBar color="#1c8e44" loaderSpeed={1500} height={2} ref={ref} shadow={false} className={"mt-[72px]"}/>*/}
{loading && <Loader />}
{HasPermission(permission) ? (
<CompanyLayout onStoreChange={(val) => setCurrentStoreId(val)}>
<div>
{resApiData ? (
<div className="px-5 pt-4 bg-slate-100 rounded-xl">
<div className="flex flex-wrap items-center justify-between pb-4">
<div>
<p className="text-xl md:text-3xl font-bold text-gray-700 capitalize">
{customer ? customer.toLowerCase() : ""}
</p>
<p className="mt-2 mb-2 text-sm font-semibold text-gray-500">
Registration Date & Time:{" "}
<span className="text-gray-700 border-gray-400">
{moment(userInfo.createdAt).format("ll LT")}
</span>
</p>
</div>
<div className="flex">
<div className="flex items-center mr-3">
<p className="pr-2 text-gray-600">
{hiddenChart ? "Disable" : "Enable"} Chart
</p>
<div className={`${styles.switch_box}`}>
<input
type="checkbox"
id="HiddenChartId"
defaultChecked={hiddenChart}
name="HiddenChartId"
onChange={(e) => HandelHiddenChart(e)}
className={` ${styles.input_switch}`}
/>
<label htmlFor="HiddenChartId" className={``} />
<div className={` ${styles.switch_status_box}`}></div>
</div>
</div>
</div>
</div>
<div className="">
{hiddenChart && (
<div className="grid grid-cols-2 md:grid-cols-4 gap-3 pt-4 pb-4 border-t">
<div className="flex items-center p-3 bg-white rounded">
<div className="ml-3">
<p className="text-xs tracking-wide text-gray-500">
Sales Amount:
</p>
<p className="mt-1 text-base font-semibold text-gray-700">
{salesAmount}
</p>
</div>
</div>
<div className="flex items-center p-3 bg-white rounded">
<div className="ml-3">
<p className="text-xs tracking-wide text-gray-500">
Tips:
</p>
<p className="mt-1 text-base font-semibold text-gray-700">
{tips}
</p>
</div>
</div>
<div className="flex items-center p-3 bg-white rounded">
<div className="ml-3">
<p className="text-xs tracking-wide text-gray-500">
Sales Amount + Tips:
</p>
<p className="mt-1 text-base font-semibold text-gray-700">
{salesPlusTips}
</p>
</div>
</div>
<div className="flex items-center p-3 bg-white rounded">
<div className="ml-3">
<p className="text-xs tracking-wide text-gray-500">
Total Amount + Fees:
</p>
<p className="mt-1 text-base font-semibold text-gray-700">
{salesPlusFees}
</p>
</div>
</div>
<div className="flex items-center p-3 bg-white rounded">
<div className="ml-3">
<p className="text-xs tracking-wide text-gray-500">
Total Processed:
</p>
<p className="mt-1 text-base font-semibold text-gray-700">
{amount}
</p>
</div>
</div>
<div className="flex items-center p-3 bg-white rounded">
<div className="ml-3">
<p className="text-xs tracking-wide text-gray-500">
Number of Transactions:
</p>
<p className="mt-1 text-base font-semibold text-gray-700">
{" "}
{noOfTransactions}
</p>
</div>
</div>
<div className="flex items-center p-3 bg-white rounded">
<div className="ml-3">
<p className="text-xs tracking-wide text-gray-500">
Returns:
</p>
<p className="mt-1 text-base font-semibold text-gray-700">
{" "}
{refund}
</p>
</div>
</div>
</div>
)}
</div>
</div>
) : (
<div className="px-5 pt-4 bg-slate-100 rounded-xl animate-pulse">
<div className="flex items-center justify-between pb-4 border-b">
<div>
<p className="h-6 rounded bg-slate-300 w-36 "></p>
<p className="h-3 mt-2 rounded bg-slate-300 w-60"></p>
</div>
<div>
<div className="inline-flex px-10 py-4 rounded bg-slate-300"></div>
</div>
</div>
<div className="grid grid-cols-4 gap-3 pt-4 pb-4 border-t">
{Array.from(Array(6), (e, i) => {
return (
<div
key={i}
className="flex items-center p-3 rounded bg-white/75"
>
{/* <div className="w-12 h-12 p-2 bg-slate-200 rounded-xl"></div> */}
<div className="ml-3">
<p className="w-20 h-2 rounded bg-slate-200 "></p>
<p className="w-10 h-4 mt-2 rounded bg-slate-200"></p>
</div>
</div>
);
})}
</div>
</div>
)}
<div className="items-center pt-7">
<h5 className="mt-4 md:mt-8 mb-4 text-xl font-semibold text-gray-700">
All Transaction
</h5>
<div className="">
<Filters
placeHolder={"Search"}
enableSearch={false}
download={true}
onDownload={handleDownload}
downloadBtn={true}
date={handleDateChange}
onSearchSubmit={handleSearchSubmit}
onSearchReset={() => setSearch("")}
downloadBtnDisable={allTransactionData}
/>
</div>
</div>
{data ? (
<div>
<div className={`${styles.table_ui_style}`}>
<Table
pending={tableLoading}
data={allTransactionData}
columns={columns}
totalRows={totalRows}
showPointer={true}
onRowClick={(val) => onRowClick(val)}
onPageChange={handleOnPageChange}
/>
</div>
</div>
) : (
<NoData />
)}
</div>
</CompanyLayout>
) : (
<Unauthorised />
)}
</>
);
}
This is the table component
import React from "react";
import DataTable from "react-data-table-component";
import { customStyles } from "./CustomTableStyle";
import LoadingTable from "./LoadingTable";
import NoData from "./widget/NoData";
function Table({
columns,
data,
totalRows,
onPageChange,
showPointer,
onRowClick,
showPagination = true,
perPage = 20,
pending,
conditionalRowStyles,
handleSort,
}) {
return (
<div className={`dash-table pt-2 md:pt-5`}>
<>
{!showPointer ? (
<DataTable
columns={columns}
data={data}
highlightOnHover={true}
defaultSortAsc={false}
striped={false}
pagination={showPagination}
paginationServer={true}
paginationTotalRows={totalRows}
customStyles={customStyles}
paginationPerPage={perPage}
paginationRowsPerPageOptions={[]}
onChangePage={(val) => onPageChange(val)}
paginationComponentOptions={{ noRowsPerPage: true }}
onColumnOrderChange={true}
progressPending={pending}
progressComponent={<LoadingTable />}
noDataComponent={<NoData />}
conditionalRowStyles={conditionalRowStyles}
onSort={handleSort}
fixedHeader
/>
) : (
<>
<DataTable
className="pagenation"
columns={columns}
data={data}
highlightOnHover={true}
defaultSortAsc={false}
striped={false}
pagination={showPagination}
paginationServer={true}
paginationTotalRows={totalRows}
customStyles={customStyles}
paginationPerPage={perPage}
paginationRowsPerPageOptions={[]}
onChangePage={(val) => onPageChange(val)}
paginationComponentOptions={{ noRowsPerPage: true }}
onRowClicked={(val) => onRowClick(val)}
pointerOnHover={true}
onColumnOrderChange={true}
progressPending={pending}
progressComponent={<LoadingTable />}
noDataComponent={<NoData />}
conditionalRowStyles={conditionalRowStyles}
onSort={handleSort}
fixedHeader
/>
{/* <LoadingTable /> */}
</>
)}
</>
</div>
);
}
export default Table;
First load -- Page 1 (Correct)
After clicking the next button -- Page 2 (Data is correct but the pagination details is not)
After clicking the next button again -- Page 2 (showing correct pagination data)