Skip to content

Commit 0eee0cd

Browse files
committed
Setup BaseTablePagination component
Setup users administration page Users administration page split into parts
1 parent 8e1d04f commit 0eee0cd

File tree

4 files changed

+213
-160
lines changed

4 files changed

+213
-160
lines changed
Lines changed: 65 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -1,184 +1,89 @@
11
import React, { useEffect, useState } from 'react'
2-
import PropTypes from 'prop-types'
3-
import api from '../../../_api'
4-
import Table from '@material-ui/core/Table'
5-
import TableBody from '@material-ui/core/TableBody'
6-
import TableCell from '@material-ui/core/TableCell'
7-
import TableContainer from '@material-ui/core/TableContainer'
8-
import TableHead from '@material-ui/core/TableHead'
9-
import TableRow from '@material-ui/core/TableRow'
10-
import Paper from '@material-ui/core/Paper'
11-
import Avatar from '@material-ui/core/Avatar'
12-
import { makeStyles, useTheme } from '@material-ui/core/styles'
13-
import TableFooter from '@material-ui/core/TableFooter'
14-
import TablePagination from '@material-ui/core/TablePagination'
15-
import IconButton from '@material-ui/core/IconButton'
16-
import FirstPageIcon from '@material-ui/icons/FirstPage'
17-
import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft'
18-
import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight'
19-
import LastPageIcon from '@material-ui/icons/LastPage'
20-
import EditIcon from '@material-ui/icons/Edit'
21-
import DeleteIcon from '@material-ui/icons/Delete'
2+
// import PropTypes from 'prop-types'
3+
4+
import Grid from '@material-ui/core/Grid'
5+
import {
6+
makeStyles,
7+
TableContainer,
8+
Table,
9+
TableCell,
10+
TableRow,
11+
TableHead,
12+
Paper,
13+
TableFooter,
14+
} from '@material-ui/core'
2215

23-
const useStyles1 = makeStyles(theme => ({
24-
root: {
25-
flexShrink: 0,
26-
marginLeft: theme.spacing(2.5),
27-
},
28-
}))
29-
30-
function TablePaginationActions(props) {
31-
const classes = useStyles1()
32-
const theme = useTheme()
33-
const { count, page, rowsPerPage, onChangePage } = props
34-
35-
const handleFirstPageButtonClick = event => {
36-
onChangePage(event, 0)
37-
}
38-
39-
const handleBackButtonClick = event => {
40-
onChangePage(event, page - 1)
41-
}
42-
43-
const handleNextButtonClick = event => {
44-
onChangePage(event, page + 1)
45-
}
46-
47-
const handleLastPageButtonClick = event => {
48-
onChangePage(event, Math.max(0, Math.ceil(count / rowsPerPage) - 1))
49-
}
50-
51-
return (
52-
<div className={classes.root}>
53-
<IconButton
54-
onClick={handleFirstPageButtonClick}
55-
disabled={page === 0}
56-
aria-label="first page"
57-
>
58-
{theme.direction === 'rtl' ? <LastPageIcon /> : <FirstPageIcon />}
59-
</IconButton>
60-
<IconButton
61-
onClick={handleBackButtonClick}
62-
disabled={page === 0}
63-
aria-label="previous page"
64-
>
65-
{theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />}
66-
</IconButton>
67-
<IconButton
68-
onClick={handleNextButtonClick}
69-
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
70-
aria-label="next page"
71-
>
72-
{theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />}
73-
</IconButton>
74-
<IconButton
75-
onClick={handleLastPageButtonClick}
76-
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
77-
aria-label="last page"
78-
>
79-
{theme.direction === 'rtl' ? <FirstPageIcon /> : <LastPageIcon />}
80-
</IconButton>
81-
</div>
82-
)
83-
}
16+
import api from '../../../_api'
8417

85-
TablePaginationActions.propTypes = {
86-
count: PropTypes.number.isRequired,
87-
onChangePage: PropTypes.func.isRequired,
88-
page: PropTypes.number.isRequired,
89-
rowsPerPage: PropTypes.number.isRequired,
90-
}
18+
import BasePageContainer from '../../../_common/BasePageContainer'
19+
import BasePageToolbar from '../../../_common/BasePageToolbar'
20+
import { BaseTablePagination } from '../../../_common/BaseTable'
9121

92-
const useStyles2 = makeStyles({
93-
table: {
94-
minWidth: 500,
95-
},
96-
})
22+
import UsersListTableBody from './UsersListTableBody'
9723

9824
const UsersList = ({ match }) => {
25+
const classes = useStyles()
9926
const [usersData, setUsersData] = useState({ users: [], count: 0 })
10027
useEffect(() => {
10128
api.users.getList().then(res => setUsersData(res))
10229
}, [])
103-
const classes = useStyles2()
30+
10431
const [page, setPage] = React.useState(0)
10532
const [rowsPerPage, setRowsPerPage] = React.useState(10)
106-
107-
const emptyRows =
108-
rowsPerPage - Math.min(rowsPerPage, usersData.users.length - page * rowsPerPage)
109-
11033
const handleChangePage = (event, newPage) => {
11134
setPage(newPage)
11235
}
11336

114-
const handleChangeRowsPerPage = event => {
115-
setRowsPerPage(parseInt(event.target.value, 10))
116-
setPage(0)
117-
}
37+
// const handleChangeRowsPerPage = event => {
38+
// setRowsPerPage(parseInt(event.target.value, 10))
39+
// setPage(0)
40+
// }
41+
42+
const { users, count } = usersData
11843

11944
return (
120-
<TableContainer component={Paper}>
121-
<Table className={classes.table} aria-label="custom pagination table">
122-
<TableHead>
123-
<TableRow>
124-
<TableCell>Avatar</TableCell>
125-
<TableCell>First Name</TableCell>
126-
<TableCell>Last Name</TableCell>
127-
<TableCell>Username</TableCell>
128-
<TableCell>Email</TableCell>
129-
<TableCell>Actions</TableCell>
130-
</TableRow>
131-
</TableHead>
132-
<TableBody>
133-
{(rowsPerPage > 0
134-
? usersData.users.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
135-
: usersData.users
136-
).map(row => (
137-
<TableRow key={row.id}>
138-
<TableCell>
139-
<Avatar alt={row.firstName} src={row.avatarUrl} />
140-
</TableCell>
141-
<TableCell component="th" scope="row">
142-
{row.firstName}
143-
</TableCell>
144-
<TableCell>{row.lastName}</TableCell>
145-
<TableCell>{row.username}</TableCell>
146-
<TableCell>{row.email}</TableCell>
147-
<TableCell>
148-
<EditIcon />
149-
<DeleteIcon />
150-
</TableCell>
151-
</TableRow>
152-
))}
153-
{emptyRows > 0 && (
154-
<TableRow style={{ height: 53 * emptyRows }}>
155-
<TableCell colSpan={6} />
156-
</TableRow>
157-
)}
158-
</TableBody>
159-
<TableFooter>
160-
<TableRow>
161-
<TablePagination
162-
rowsPerPageOptions={[5, 10, 25, { label: 'All', value: -1 }]}
163-
colSpan={12}
164-
count={usersData.users.length}
165-
rowsPerPage={rowsPerPage}
166-
page={page}
167-
SelectProps={{
168-
inputProps: { 'aria-label': 'rows per page' },
169-
native: true,
170-
}}
171-
onChangePage={handleChangePage}
172-
onChangeRowsPerPage={handleChangeRowsPerPage}
173-
ActionsComponent={TablePaginationActions}
174-
/>
175-
</TableRow>
176-
</TableFooter>
177-
</Table>
178-
</TableContainer>
45+
<BasePageContainer>
46+
<BasePageToolbar title={'Users Adminstration'}></BasePageToolbar>
47+
<Grid container spacing={3}>
48+
<Grid item xs={12}>
49+
<TableContainer component={Paper}>
50+
<Table className={classes.table} aria-label="custom pagination table">
51+
<TableHead>
52+
<TableRow>
53+
<TableCell>Avatar</TableCell>
54+
<TableCell>First Name</TableCell>
55+
<TableCell>Last Name</TableCell>
56+
<TableCell>Username</TableCell>
57+
<TableCell>Email</TableCell>
58+
<TableCell>Actions</TableCell>
59+
</TableRow>
60+
</TableHead>
61+
<UsersListTableBody users={users} count={count} rowsPerPage={rowsPerPage} />
62+
<TableFooter>
63+
<TableRow>
64+
<BaseTablePagination
65+
page={page}
66+
rowsPerPage={rowsPerPage}
67+
count={count}
68+
onChangePage={handleChangePage}
69+
/>
70+
</TableRow>
71+
</TableFooter>
72+
</Table>
73+
</TableContainer>
74+
</Grid>
75+
</Grid>
76+
</BasePageContainer>
17977
)
18078
}
18179

80+
const useStyles = makeStyles(theme => ({
81+
root: {
82+
flexShrink: 0,
83+
marginLeft: theme.spacing(2.5),
84+
},
85+
}))
86+
18287
UsersList.propTypes = {}
18388

18489
export default UsersList
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React from 'react'
2+
import PropTypes from 'prop-types'
3+
4+
import { makeStyles, TableBody, TableCell, TableRow, Avatar } from '@material-ui/core'
5+
6+
import { Edit as EditIcon, Delete as DeleteIcon } from '@material-ui/icons/'
7+
8+
const UsersListTableBody = ({ users, page, rowsPerPage = 10, Pagination }) => {
9+
const classes = useStyles()
10+
11+
// Count how many empty rows needs to be filled
12+
const emptyRows = rowsPerPage - users.length
13+
14+
return (
15+
<TableBody>
16+
{users.map(row => (
17+
<TableRow key={row.id}>
18+
<TableCell>
19+
<Avatar alt={row.firstName} src={row.avatarUrl} />
20+
</TableCell>
21+
<TableCell component="th" scope="row">
22+
{row.firstName}
23+
</TableCell>
24+
<TableCell>{row.lastName}</TableCell>
25+
<TableCell>{row.username}</TableCell>
26+
<TableCell>{row.email}</TableCell>
27+
<TableCell>
28+
<EditIcon />
29+
<DeleteIcon />
30+
</TableCell>
31+
</TableRow>
32+
))}
33+
{emptyRows > 0 && (
34+
<TableRow style={{ height: 53 * emptyRows }}>
35+
<TableCell colSpan={6} />
36+
</TableRow>
37+
)}
38+
</TableBody>
39+
)
40+
}
41+
42+
UsersListTableBody.propTypes = {}
43+
44+
const useStyles = makeStyles(theme => ({
45+
root: {
46+
flexShrink: 0,
47+
marginLeft: theme.spacing(2.5),
48+
},
49+
}))
50+
51+
export default UsersListTableBody
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import React from 'react'
2+
import PropTypes from 'prop-types'
3+
import { TablePagination, IconButton } from '@material-ui/core'
4+
import { useTheme } from '@material-ui/core/styles'
5+
6+
import {
7+
FirstPage as FirstPageIcon,
8+
KeyboardArrowLeft,
9+
KeyboardArrowRight,
10+
LastPage as LastPageIcon,
11+
} from '@material-ui/icons/'
12+
13+
const BaseTablePaginationActions = props => {
14+
const theme = useTheme()
15+
const { count, page, itemsPerPage, onChangePage } = props
16+
17+
const handleFirstPageButtonClick = event => {
18+
onChangePage(event, 0)
19+
}
20+
21+
const handleBackButtonClick = event => {
22+
onChangePage(event, page - 1)
23+
}
24+
25+
const handleNextButtonClick = event => {
26+
onChangePage(event, page + 1)
27+
}
28+
29+
const handleLastPageButtonClick = event => {
30+
onChangePage(event, Math.max(0, Math.ceil(count / itemsPerPage) - 1))
31+
}
32+
33+
return (
34+
<div>
35+
<IconButton
36+
onClick={handleFirstPageButtonClick}
37+
disabled={page === 0}
38+
aria-label="first page"
39+
>
40+
{theme.direction === 'rtl' ? <LastPageIcon /> : <FirstPageIcon />}
41+
</IconButton>
42+
<IconButton
43+
onClick={handleBackButtonClick}
44+
disabled={page === 0}
45+
aria-label="previous page"
46+
>
47+
{theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />}
48+
</IconButton>
49+
<IconButton
50+
onClick={handleNextButtonClick}
51+
disabled={page >= Math.ceil(count / itemsPerPage) - 1}
52+
aria-label="next page"
53+
>
54+
{theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />}
55+
</IconButton>
56+
<IconButton
57+
onClick={handleLastPageButtonClick}
58+
disabled={page >= Math.ceil(count / itemsPerPage) - 1}
59+
aria-label="last page"
60+
>
61+
{theme.direction === 'rtl' ? <FirstPageIcon /> : <LastPageIcon />}
62+
</IconButton>
63+
</div>
64+
)
65+
}
66+
67+
const BaseTablePagination = props => {
68+
const { count, page, rowsPerPage, onChangePage } = props
69+
70+
return (
71+
<TablePagination
72+
rowsPerPageOptions={[5, 10, 25, 50]}
73+
colSpan={12}
74+
count={count}
75+
rowsPerPage={rowsPerPage}
76+
page={page}
77+
SelectProps={{
78+
inputProps: { 'aria-label': 'rows per page' },
79+
native: true,
80+
}}
81+
onChangePage={onChangePage}
82+
ActionsComponent={BaseTablePaginationActions}
83+
/>
84+
)
85+
}
86+
87+
BaseTablePagination.propTypes = {
88+
count: PropTypes.number.isRequired,
89+
onChangePage: PropTypes.func.isRequired,
90+
page: PropTypes.number.isRequired,
91+
rowsPerPage: PropTypes.number.isRequired,
92+
}
93+
94+
export default BaseTablePagination

0 commit comments

Comments
 (0)