diff --git a/src/pages/Fiber/Channel/index.module.scss b/src/pages/Fiber/Channel/index.module.scss index 7fdd5c4b0..e84dcc914 100644 --- a/src/pages/Fiber/Channel/index.module.scss +++ b/src/pages/Fiber/Channel/index.module.scss @@ -1,4 +1,5 @@ -@import '../../../styles//variables.module.scss'; +@import '../../../styles/variables.module'; +@import '../../../styles/card.module'; .container { text-wrap: nowrap; diff --git a/src/pages/Fiber/Pagination/index.module.scss b/src/pages/Fiber/Pagination/index.module.scss new file mode 100644 index 000000000..2a189997a --- /dev/null +++ b/src/pages/Fiber/Pagination/index.module.scss @@ -0,0 +1,95 @@ +@import '../../../styles/variables.module'; + +.container { + display: flex; + background: #fff; + justify-content: space-between; + height: 34px; + + form { + display: flex; + gap: 20px; + + label { + display: flex; + align-items: center; + } + + button { + display: flex; + justify-content: center; + width: 50px; + background: #f5f5f5; + border-radius: 6px; + } + + input { + width: 100; + padding: 0 10px; + color: #969696; + border-radius: 6px; + background: #f5f5f5; + border: none; + } + } + + .pager { + display: flex; + gap: 20px; + + .pageNo { + display: flex; + align-items: center; + } + } + + a { + display: flex; + justify-content: center; + align-items: center; + color: #969696; + + &:hover { + color: var(--primary-color); + } + + &[aria-disabled='true'] { + pointer-events: none; + opacity: 0.5; + } + + &[data-role='first-page'], + &[data-role='last-page'] { + width: 50px; + background: #f5f5f5; + border-radius: 6px; + } + + &[data-role='prev-page'], + &[data-role='next-page'] { + width: 30px; + height: 30px; + background: #f5f5f5; + border-radius: 6px; + } + } + + @media screen and (width < $mobileBreakPoint) { + font-size: 12px; + + .pager { + gap: 4px; + } + + a { + &[data-role='first-page'], + &[data-role='last-page'] { + display: none; + } + } + + .pageNo { + order: 3; + } + } +} diff --git a/src/pages/Fiber/Pagination/index.tsx b/src/pages/Fiber/Pagination/index.tsx new file mode 100644 index 000000000..5e60d5cba --- /dev/null +++ b/src/pages/Fiber/Pagination/index.tsx @@ -0,0 +1,68 @@ +import React from 'react' +import { Link, useHistory } from 'react-router-dom' +import { ChevronLeftIcon, ChevronRightIcon } from '@radix-ui/react-icons' +import { useSearchParams } from '../../../hooks' +import styles from './index.module.scss' + +interface PaginationProps { + totalPages: number +} + +const getPageUrl = (page: number, search: URLSearchParams) => { + search.set('page', page.toString()) + return `${window.location.pathname}?${search.toString()}` +} + +const Pagination: React.FC = ({ totalPages }) => { + const history = useHistory() + const { page: p } = useSearchParams('page') + + // Get the current page from the URL query parameter, defaulting to 1 if not set + const currentPage = Number(p) || 1 + const search = new URLSearchParams(window.location.search) + + const handleGo = (e: React.SyntheticEvent) => { + e.stopPropagation() + e.preventDefault() + + const { page } = e.currentTarget + if (!(page instanceof HTMLInputElement)) return + const go = page.value + if (+go < 1) { + history.push(getPageUrl(1, search)) + return + } + if (+go > totalPages) { + history.push(getPageUrl(totalPages, search)) + return + } + history.push(getPageUrl(+go, search)) + } + + return ( +
+
+ + First + + + + + {`Page ${currentPage} of ${totalPages}`} + + + + + Last + +
+
+ + + +
+
+ ) +} + +export default Pagination diff --git a/src/pages/Fiber/Peer/index.module.scss b/src/pages/Fiber/Peer/index.module.scss index 7313b7d28..ace74b7cd 100644 --- a/src/pages/Fiber/Peer/index.module.scss +++ b/src/pages/Fiber/Peer/index.module.scss @@ -1,4 +1,5 @@ -@import '../../../styles//variables.module.scss'; +@import '../../../styles/variables.module'; +@import '../../../styles/card.module'; .container { text-wrap: nowrap; @@ -71,13 +72,11 @@ } .overview { + @extend %base-card; + display: flex; justify-content: space-between; flex-wrap: wrap; - background: #fff; - border-radius: 6px; - padding: 16px; - box-shadow: 0 2px 6px 0 #4d4d4d33; .fields { overflow: hidden; diff --git a/src/pages/Fiber/PeerList/index.module.scss b/src/pages/Fiber/PeerList/index.module.scss index 3daa3ca18..25e11803e 100644 --- a/src/pages/Fiber/PeerList/index.module.scss +++ b/src/pages/Fiber/PeerList/index.module.scss @@ -14,6 +14,10 @@ table { @extend %base-table; + + tr[data-role='pagination']:hover { + background: #fff; + } } svg { @@ -105,10 +109,12 @@ @media screen and (width < 810px) { table { - th, - td { - &:last-child { - display: none; + tr:not([data-role='pagination']) { + th, + td { + &:last-child { + display: none; + } } } } diff --git a/src/pages/Fiber/PeerList/index.tsx b/src/pages/Fiber/PeerList/index.tsx index 27e421281..d2620492c 100644 --- a/src/pages/Fiber/PeerList/index.tsx +++ b/src/pages/Fiber/PeerList/index.tsx @@ -12,6 +12,8 @@ import { localeNumberString } from '../../../utils/number' import { parseNumericAbbr } from '../../../utils/chart' import styles from './index.module.scss' import AddPeerForm from './AddPeerForm' +import Pagination from '../Pagination' +import { PAGE_SIZE } from '../../../constants/common' const fields = [ { @@ -127,6 +129,8 @@ const PeerList = () => { }) const list = data?.data.fiberPeers ?? [] + const pageInfo = data?.data.meta ?? { total: 1, pageSize: PAGE_SIZE } + const totalPages = Math.ceil(pageInfo.total / pageInfo.pageSize) const handleCopy = (e: React.SyntheticEvent) => { const elm = e.target @@ -166,8 +170,13 @@ const PeerList = () => { ) })} +
+ + + + + - {/*
*/}
diff --git a/src/styles/card.module.scss b/src/styles/card.module.scss new file mode 100644 index 000000000..6d5d707bd --- /dev/null +++ b/src/styles/card.module.scss @@ -0,0 +1,6 @@ +%base-card { + background: #fff; + border-radius: 6px; + padding: 16px; + box-shadow: 0 2px 6px 0 #4d4d4d33; +}