1
- import React , { useState , useEffect } from "react" ;
1
+ import React , { useState , useEffect , useCallback } from "react" ;
2
2
import MenuItem from "@mui/material/MenuItem" ;
3
3
import Select , { SelectChangeEvent } from "@mui/material/Select" ;
4
4
import InputLabel from "@mui/material/InputLabel" ;
5
5
import {
6
- TableContainer ,
7
- Paper ,
8
- TableBody ,
9
6
TableRow ,
10
7
TableCell ,
11
- TableFooter ,
12
8
TablePagination ,
13
- TableHead ,
14
9
Stack ,
15
10
FormControl ,
16
11
} from "@mui/material" ;
17
12
import TablePaginationActions from "@mui/material/TablePagination/TablePaginationActions" ;
18
- import { Table } from "react-bootstrap" ;
13
+ import CustomTable from "../common/table/CustomTable" ;
14
+ import useTable from "../../hooks/useTable" ;
19
15
import { Role } from "../../types/AuthTypes" ;
20
16
import UserAPIClient from "../../APIClients/UserAPIClient" ;
21
17
import { User } from "../../types/UserTypes" ;
22
18
23
19
const ManageUser = ( ) : React . ReactElement => {
24
20
const [ role , setRole ] = useState < Role > ( "Administrator" ) ;
25
21
const [ users , setUsers ] = useState < User [ ] > ( [ ] ) ;
26
- const [ page , setPage ] = useState ( 1 ) ;
27
- const [ usersPerPage , setUsersPerPage ] = useState ( 10 ) ;
22
+
23
+ const {
24
+ paginatedData,
25
+ handleChangePage,
26
+ handleChangeRowsPerPage,
27
+ pageSize,
28
+ page,
29
+ setSortField,
30
+ setSortAscending,
31
+ sortField,
32
+ } = useTable ( {
33
+ data : users ,
34
+ } ) ;
35
+
28
36
useEffect ( ( ) => {
29
37
async function getUsers ( ) {
30
38
const fetchedUsers = await UserAPIClient . getUsersByRole ( role ) ;
31
39
setUsers ( fetchedUsers ) ;
32
- setPage ( 0 ) ;
40
+ handleChangePage ( 0 ) ;
33
41
}
34
42
getUsers ( ) ;
35
43
} , [ role ] ) ;
36
44
37
- const emptyRows =
38
- page > 0 ? Math . max ( 0 , ( 1 + page ) * usersPerPage - users . length ) : 0 ;
45
+ const setSortFieldAndSortDirection = useCallback (
46
+ ( selectedSortField : keyof User ) => {
47
+ if ( selectedSortField === sortField ) {
48
+ setSortAscending ( ( prev ) => ! prev ) ;
49
+ } else {
50
+ setSortField ( selectedSortField ) ;
51
+ setSortAscending ( true ) ;
52
+ }
53
+ } ,
54
+ [ setSortField , setSortAscending , sortField ] ,
55
+ ) ;
56
+
57
+ const changePage = useCallback (
58
+ ( event : React . MouseEvent < HTMLButtonElement > | null , newPage : number ) => {
59
+ handleChangePage ( newPage ) ;
60
+ } ,
61
+ [ handleChangePage ] ,
62
+ ) ;
63
+
64
+ const changeRowsPerPage = useCallback (
65
+ ( event : React . ChangeEvent < HTMLInputElement | HTMLTextAreaElement > ) => {
66
+ handleChangeRowsPerPage ( parseInt ( event . target . value , 10 ) ) ;
67
+ handleChangePage ( 0 ) ;
68
+ } ,
69
+ [ handleChangePage , handleChangeRowsPerPage ] ,
70
+ ) ;
71
+
72
+ const renderHead = useCallback ( ( ) => {
73
+ return (
74
+ < TableRow >
75
+ < TableCell onClick = { ( ) => setSortFieldAndSortDirection ( "email" ) } >
76
+ Email
77
+ </ TableCell >
78
+ < TableCell
79
+ align = "right"
80
+ onClick = { ( ) => setSortFieldAndSortDirection ( "firstName" ) }
81
+ >
82
+ First Name
83
+ </ TableCell >
84
+ < TableCell
85
+ align = "right"
86
+ onClick = { ( ) => setSortFieldAndSortDirection ( "lastName" ) }
87
+ >
88
+ Last Name
89
+ </ TableCell >
90
+ </ TableRow >
91
+ ) ;
92
+ } , [ setSortFieldAndSortDirection ] ) ;
93
+
94
+ const renderRow = useCallback ( ( user : User ) => {
95
+ return (
96
+ < TableRow style = { { height : 53 } } >
97
+ < TableCell component = "th" scope = "row" >
98
+ { user . email }
99
+ </ TableCell >
100
+ < TableCell style = { { width : 160 } } align = "right" >
101
+ { user . firstName }
102
+ </ TableCell >
103
+ < TableCell style = { { width : 160 } } align = "right" >
104
+ { user . lastName }
105
+ </ TableCell >
106
+ </ TableRow >
107
+ ) ;
108
+ } , [ ] ) ;
39
109
40
- const handleChangePage = (
41
- event : React . MouseEvent < HTMLButtonElement > | null ,
42
- newPage : number ,
43
- ) => {
44
- setPage ( newPage ) ;
45
- } ;
110
+ const renderFooter = useCallback ( ( ) => {
111
+ return (
112
+ < TableRow >
113
+ < TablePagination
114
+ rowsPerPageOptions = { [ 5 , 10 , 25 , { label : "All" , value : - 1 } ] }
115
+ colSpan = { 3 }
116
+ count = { users . length }
117
+ rowsPerPage = { pageSize }
118
+ page = { page }
119
+ slotProps = { {
120
+ select : {
121
+ inputProps : {
122
+ "aria-label" : "users per page" ,
123
+ } ,
124
+ native : true ,
125
+ } ,
126
+ } }
127
+ onPageChange = { changePage }
128
+ onRowsPerPageChange = { changeRowsPerPage }
129
+ ActionsComponent = { TablePaginationActions }
130
+ />
131
+ </ TableRow >
132
+ ) ;
133
+ } , [ changePage , changeRowsPerPage , page , pageSize , users . length ] ) ;
46
134
47
- const handleChangeRowsPerPage = (
48
- event : React . ChangeEvent < HTMLInputElement | HTMLTextAreaElement > ,
49
- ) => {
50
- setUsersPerPage ( parseInt ( event . target . value , 10 ) ) ;
51
- setPage ( 0 ) ;
52
- } ;
135
+ const getKey = useCallback ( ( user : User ) => {
136
+ return user . id ;
137
+ } , [ ] ) ;
53
138
54
139
return (
55
140
< Stack direction = "column" justifyContent = "center" margin = "2rem" spacing = { 2 } >
@@ -69,65 +154,13 @@ const ManageUser = (): React.ReactElement => {
69
154
< MenuItem value = "Learner" > Learner</ MenuItem >
70
155
</ Select >
71
156
</ FormControl >
72
- < TableContainer component = { Paper } >
73
- < Table aria-label = "User grouped by role table" >
74
- < TableHead >
75
- < TableRow >
76
- < TableCell > Email</ TableCell >
77
- < TableCell align = "right" > First Name</ TableCell >
78
- < TableCell align = "right" > Last Name</ TableCell >
79
- </ TableRow >
80
- </ TableHead >
81
- < TableBody >
82
- { ( usersPerPage > 0
83
- ? users . slice (
84
- page * usersPerPage ,
85
- page * usersPerPage + usersPerPage ,
86
- )
87
- : users
88
- ) . map ( ( user ) => (
89
- < TableRow key = { user . id } style = { { height : 53 } } >
90
- < TableCell component = "th" scope = "row" >
91
- { user . email }
92
- </ TableCell >
93
- < TableCell style = { { width : 160 } } align = "right" >
94
- { user . firstName }
95
- </ TableCell >
96
- < TableCell style = { { width : 160 } } align = "right" >
97
- { user . lastName }
98
- </ TableCell >
99
- </ TableRow >
100
- ) ) }
101
- { emptyRows > 0 && (
102
- < TableRow style = { { height : 53 * emptyRows } } >
103
- < TableCell colSpan = { 6 } />
104
- </ TableRow >
105
- ) }
106
- </ TableBody >
107
- < TableFooter >
108
- < TableRow >
109
- < TablePagination
110
- rowsPerPageOptions = { [ 5 , 10 , 25 , { label : "All" , value : - 1 } ] }
111
- colSpan = { 3 }
112
- count = { users . length }
113
- rowsPerPage = { usersPerPage }
114
- page = { page }
115
- slotProps = { {
116
- select : {
117
- inputProps : {
118
- "aria-label" : "users per page" ,
119
- } ,
120
- native : true ,
121
- } ,
122
- } }
123
- onPageChange = { handleChangePage }
124
- onRowsPerPageChange = { handleChangeRowsPerPage }
125
- ActionsComponent = { TablePaginationActions }
126
- />
127
- </ TableRow >
128
- </ TableFooter >
129
- </ Table >
130
- </ TableContainer >
157
+ < CustomTable
158
+ data = { paginatedData }
159
+ renderRow = { renderRow }
160
+ renderHead = { renderHead }
161
+ renderFooter = { renderFooter }
162
+ getKey = { getKey }
163
+ />
131
164
</ Stack >
132
165
) ;
133
166
} ;
0 commit comments