-
Notifications
You must be signed in to change notification settings - Fork 0
/
PaginatedTableContainer.tsx
105 lines (94 loc) · 3.17 KB
/
PaginatedTableContainer.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import React, { useCallback, useEffect, useState } from "react";
import DataListTable from "../../components/DataListTable/DataListTable";
import Pagination from "../../components/Pagination/Pagination";
import { useDebounce } from "use-debounce";
import Filters from "../../components/Filters/Filters";
import type { Data } from "../../types/data";
import { fetchData, FetchDataParams } from "../../services/data.service";
import type { PaginatedDataResponse } from "../../types/paginatedDataResponse";
const INPUT_DEBOUNCE_TIME = 300;
function PaginatedTableContainer() {
const [data, setData] = useState<Data[]>([]);
const [totalItems, setTotalItems] = useState<number>(0);
const [totalPages, setTotalPages] = useState<number>(0);
const [currentPage, setCurrentPage] = useState<number>(1);
const [statusFilter, setStatusFilter] = useState<string>("");
const [nameFilter, setNameFilter] = useState<string>("");
const [itemsPerPage, setItemsPerPage] = useState<number>(20);
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null);
const [debouncedNameFilter] = useDebounce(nameFilter, INPUT_DEBOUNCE_TIME);
const getData = useCallback(
async ({ page, status, name, limit }: FetchDataParams) => {
setLoading(true);
setError(null);
try {
const response: PaginatedDataResponse = await fetchData({
status,
name,
limit,
page,
});
setData(response.data);
setTotalItems(response.totalItems);
setTotalPages(response.totalPages);
setCurrentPage(response.currentPage);
} catch (err) {
setError("Failed to fetch data. Please try again.");
console.error(err);
} finally {
setLoading(false);
}
},
[]
);
useEffect(() => {
getData({
page: currentPage,
status: statusFilter,
name: debouncedNameFilter,
limit: itemsPerPage,
});
}, [currentPage, statusFilter, debouncedNameFilter, itemsPerPage, getData]);
const handlePageChange = (newPage: number) => {
setCurrentPage(newPage);
};
const handleStatusFilterChange = (newStatus: string) => {
setStatusFilter(newStatus);
setCurrentPage(1);
};
const handleNameFilterChange = useCallback((newName: string) => {
setNameFilter(newName);
setCurrentPage(1);
}, []);
return (
<div className="paginatedTableContainer">
<Filters
nameFilter={nameFilter}
statusFilter={statusFilter}
onStatusFilterChange={handleStatusFilterChange}
onNameFilterChange={handleNameFilterChange}
totalItems={totalItems}
/>
{loading ? (
<div className="loading">
<p>Loading...</p>
</div>
) : error ? (
<p className="error">{error}</p>
) : (
<>
<DataListTable data={data} />
<Pagination
currentPage={currentPage}
totalPages={totalPages}
itemsPerPage={itemsPerPage}
onPageChange={handlePageChange}
onItemsPerPageChange={setItemsPerPage}
/>
</>
)}
</div>
);
}
export default PaginatedTableContainer;