Skip to content

Commit

Permalink
Add pagination components
Browse files Browse the repository at this point in the history
  • Loading branch information
bbahd30 committed Jan 16, 2024
1 parent 1ea34fc commit 51e9411
Show file tree
Hide file tree
Showing 9 changed files with 316 additions and 282 deletions.
2 changes: 1 addition & 1 deletion src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const App = ({ match , getMaintainers }) => {

return (
<Scrollbars autoHide>
<div className={tailwindWrapper("py-4 pl-6 pr-9 h-[100%] font-Inter")}>
<div className={tailwindWrapper("py-4 md:px-9 px-4 h-[100%] font-Inter")}>
<span className={tailwindWrapper("flex-grow-2 text-xl text-black-500 font-semibold")}>Helpcentre</span>
<Switch>
<Route exact path={`${match.path}`} component={Home} />
Expand Down
4 changes: 2 additions & 2 deletions src/components/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { urlStatic } from '../urls'

const Dropdown = ({ options, selectedOption, setOption, open, setOpen, otherContent, width, placeholder }) => {
const theme = getTheme()
console.log(selectedOption)

return (
<div className={tailwindWrapper(`relative cursor-pointer ${width} ${!open && "border-2 border-[#F5F5F5]"} rounded-sm`)} onClick={() => {setOpen(!open)}}>
<div className={tailwindWrapper(`w-full p-2 pr-4 flex justify-between items-center ${open ? "border rounded-md " + themeBorder[theme] : ""}`)}>
Expand All @@ -19,7 +19,7 @@ const Dropdown = ({ options, selectedOption, setOption, open, setOpen, otherCont
{open && <ul className={tailwindWrapper("absolute w-full bg-white border border-x-2 border-b-2 border-#F5F5F5")}>
{options && options.map((item) => (
<li key={item.key} onClick={() => setOption(item.value, item.text)} className={tailwindWrapper("flex justify-content items-center text-sm px-3 py-2 hover:bg-[#00000008] gap-2")}>
{item.content || otherContent()}
{item.content || otherContent()}
<span className={tailwindWrapper(selectedOption === item.text ? "font-bold" : "")}>{item.text}</span>
</li>
))}
Expand Down
6 changes: 3 additions & 3 deletions src/components/home.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,18 @@ const Home = ({ appList, SetAppList }) => {
return (
<div>
<div>
<div className={tailwindWrapper("flex justify-between")}>
<div className={tailwindWrapper("flex max-[400px]:flex-col gap-3 justify-between")}>
<SearchBar />
<Link to="/helpcentre/issues" className={tailwindWrapper("mt-auto")}>
<button className={tailwindWrapper(`text-white text-sm h-max rounded-md px-6 py-2.5 ${themeBg[theme]}`)}>
<button className={tailwindWrapper(`block ml-auto text-white text-sm h-max rounded-md px-6 py-2.5 ${themeBg[theme]}`)}>
Report Issue
</button>
</Link>
</div>
</div>
<div className={tailwindWrapper("flex flex-col md:flex-row justify-between h-full mt-12 px-4")}>
<div className={tailwindWrapper("md:w-2/3")}>
<Dropdown options={options} selectedOption={selectedApp} setOption={setApp} open={open} setOpen={setOpen} width={"w-full"} otherContent={OtherApp} placeholder={"Select an App"}/>
<Dropdown options={options} selectedOption={selectedApp} setOption={setApp} open={open} setOpen={setOpen} width={"w-full md:w-2/3"} otherContent={OtherApp} placeholder={"Select an App"}/>
<Accordion faqText={faqText} />
</div>
<div>
Expand Down
48 changes: 43 additions & 5 deletions src/components/icons.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React from "react"
import { tailwindWrapper } from "formula_one/src/utils/tailwindWrapper"
import { themeText } from "../constants/theme"
import { getTheme } from 'formula_one'

export const PendingIcon = ({isActive}) => (
<svg xmlns="http://www.w3.org/2000/svg" fill={isActive ? "red" : "none"} viewBox="0 0 24 24" strokeWidth={isActive ? "2.5" : "1.5"} stroke={isActive ? "white" : "black"} className={tailwindWrapper("w-6 h-6")}>
<path strokeLinecap="round" strokeLinejoin="round" d="M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z" />
</svg>
export const PendingIcon = ({ isActive, fill, stroke }) => (
<svg xmlns="http://www.w3.org/2000/svg" fill={fill || (isActive ? "red" : "none")} viewBox="0 0 24 24" strokeWidth={isActive ? "2.5" : "1.5"} stroke={stroke || (isActive ? "white" : "black")} className={tailwindWrapper("w-6 h-6")}>
<path strokeLinecap="round" strokeLinejoin="round" d="M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z" />
</svg>
)

export const ResolvedIcon = () => (
Expand All @@ -24,4 +26,40 @@ export const OtherApp = () => (
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className={tailwindWrapper("w-6 h-6 mr-2.5")}>
<path strokeLinecap="round" strokeLinejoin="round" d="m21 7.5-9-5.25L2.5 7.5m18 0-9 5.25m9-5.25v9l-9 5.25M3 7.5l9 5.25M3 7.5v9l9 5.25m0-9v9" />
</svg>
)
)

export const ChevronLeft = () => (
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className={tailwindWrapper("w-4 h-full cursor-pointer")}>
<path strokeLinecap="round" strokeLinejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5" />
</svg>
)

export const ChevronRight = () => (
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className={tailwindWrapper("w-4 h-full cursor-pointer")}>
<path strokeLinecap="round" strokeLinejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" />
</svg>
)

export const ChevronDoubleLeft = () => (
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className={tailwindWrapper("w-4 h-full cursor-pointer")}>
<path strokeLinecap="round" strokeLinejoin="round" d="m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5" />
</svg>
)

export const ChevronDoubleRight = () => (
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className={tailwindWrapper("w-4 h-full cursor-pointer")}>
<path strokeLinecap="round" strokeLinejoin="round" d="m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5" />
</svg>
)

export const ShieldIcon = () => (
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className={tailwindWrapper(`${themeText[getTheme()]} w-6 h-6 inline-block`)}>
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75 11.25 15 15 9.75m-3-7.036A11.959 11.959 0 0 1 3.598 6 11.99 11.99 0 0 0 3 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285Z" />
</svg>
)

export const DownloadIcon = () => (
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className={tailwindWrapper("w-6 h-6")}>
<path strokeLinecap="round" strokeLinejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
</svg>
)
62 changes: 62 additions & 0 deletions src/components/pagination.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React, { useEffect, useState } from 'react'
import { tailwindWrapper } from "formula_one/src/utils/tailwindWrapper"
import { ChevronDoubleLeft, ChevronDoubleRight, ChevronLeft, ChevronRight } from './icons'
import { themeBg } from '../constants/theme'

import {getTheme} from 'formula_one'

const Pagination = ({ totalPages, activePage, onPageChange }) => {
const pages = Array.from({ length: totalPages }, (_, index) => index + 1)
const [visibleBtns, setVisibleBtns] = useState([])
const [maxPageLimit, setMaxPageLimit] = useState(5)
const [minPageLimit, setMinPageLimit] = useState(1)
const pageLimit = 5
const theme = getTheme()

useEffect(() => {
if (activePage > maxPageLimit) {
setMaxPageLimit(maxPageLimit + pageLimit)
setMinPageLimit(minPageLimit + pageLimit)
}
if (activePage < minPageLimit) {
setMaxPageLimit(maxPageLimit - pageLimit)
setMinPageLimit(minPageLimit - pageLimit)
}

const visiblePages = pages.filter(
(page) => page >= minPageLimit && page <= maxPageLimit
)

setVisibleBtns(visiblePages)
}, [activePage, totalPages, maxPageLimit, minPageLimit, pageLimit])

const dotsStyle = tailwindWrapper(`px-4 py-2 hover:bg-gray-200`)
const btnStyle = (index) => tailwindWrapper(`${activePage === index ? 'opacity-50 pointer-events-none' : ''} px-4 py-2 hover:bg-gray-200`)

return (
<div className={tailwindWrapper("flex items-stretch items-center border justify-start")}>

<div onClick={() => onPageChange(1)} className={btnStyle(1)}><ChevronDoubleLeft /></div>
<div onClick={() => onPageChange(activePage - 1)} className={btnStyle(1)}><ChevronLeft /></div>

{minPageLimit !== 1 &&
<div onClick={() => onPageChange(Math.max(1 , minPageLimit - pageLimit))} className={dotsStyle}>...</div>}

{totalPages > 0
? visibleBtns.map((page) => (
<div key={page} onClick={() => onPageChange(page)} className={tailwindWrapper(`px-4 py-2 ${page === activePage ? themeBg[theme] + " text-white" : 'hover:bg-gray-200'}`)}>
{page}
</div>
))
: <div className={dotsStyle}>...</div>}

{totalPages > maxPageLimit &&
<div onClick={() => onPageChange(Math.min(totalPages, maxPageLimit + pageLimit))} className={dotsStyle}>...</div>}

<div onClick={() => onPageChange(activePage + 1)} className={btnStyle(totalPages)}><ChevronRight /></div>
<div onClick={() => onPageChange(totalPages)} className={btnStyle(totalPages)}><ChevronDoubleRight /></div>
</div>
)
}

export default Pagination
2 changes: 1 addition & 1 deletion src/components/searchbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { tailwindWrapper } from "formula_one/src/utils/tailwindWrapper"

const SearchBar = () => {
return (
<div className={tailwindWrapper("flex justify-between items-center pl-4 rounded-lg border-2 border-[#F5F5F5] w-full md:w-[40%] mt-2.5")}>
<div className={tailwindWrapper("flex justify-between items-center pl-4 rounded-lg border-2 border-[#F5F5F5] md:w-[40%] w-[60%] max-[400px]:w-full mt-2.5")}>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="#4C4C4C" className={tailwindWrapper("w-5 h-5")}>
<path strokeLinecap="round" strokeLinejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" />
</svg>
Expand Down
177 changes: 74 additions & 103 deletions src/components/tab-pagination.js
Original file line number Diff line number Diff line change
@@ -1,117 +1,88 @@
import React, { Component } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import { connect } from 'react-redux'
import { Icon, Input, Pagination } from 'semantic-ui-react'
import { MobileView, BrowserView } from 'react-device-detect'
import { BrowserView, MobileView } from 'react-device-detect'

import Pagination from './pagination'
import { tailwindWrapper } from "formula_one/src/utils/tailwindWrapper"
import { setIssueList, changePage, setUser, setStatusNumbers } from '../actions'

class TabPagination extends Component {
componentDidMount () {
this.props.SetUser()
this.props.SetStatusNumbers()
this.props.SetIssueList(1, 'opened')
}
const TabPagination = ({ issueList, page, SetUser, SetStatusNumbers, SetIssueList, ChangePage }) => {
const inputRef = useRef(null)
const [activePage, setActivePage ] = useState(1)
const [totalPages, setTotalPages] = useState(1)

handleRef = c => {
this.inputRef = c
}
useEffect(() => {
setTotalPages(Math.ceil(issueList['count'] / 10))
}, [issueList])

handlePageChange = (event, data) => {
this.props.ChangePage(data['activePage'], this.props.page['status'])
this.props.SetIssueList(data['activePage'], this.props.page['status'])
}
useEffect(() => {
setActivePage(page.index)
}, [page])

useEffect(() => {
SetUser()
SetStatusNumbers()
SetIssueList(1, 'opened')
}, [SetUser, SetStatusNumbers, SetIssueList])

handleInputChange = event => {
this.props.ChangePage(event.target.value, this.props.page['status'])
this.props.SetIssueList(event.target.value, this.props.page['status'])
}
const handlePageChange = (activePage) => {
if(activePage < 1 || activePage > totalPages)
return
ChangePage(activePage, page.status)
SetIssueList(activePage, page.status)
setCurrentPage(activePage)
}

handleKeyPress = event => {
if (event.key === 'Enter') {
this.props.ChangePage(event.target.value, this.props.page['status'])
this.props.SetIssueList(event.target.value, this.props.page['status'])
this.inputRef.blur()
const handleInputChange = (event) => {
ChangePage(event.target.value, page.status)
SetIssueList(event.target.value, page.status)
}

const handleKeyPress = (event) => {
if (event.key === 'Enter') {
ChangePage(event.target.value, page.status)
SetIssueList(event.target.value, page.status)
inputRef.current.blur()
}
}
}
render () {

return (
<React.Fragment>
<BrowserView>
<Pagination
activePage={this.props.page['index'] && this.props.page['index']}
totalPages={
this.props.issueList
? Math.ceil(this.props.issueList['count'] / 10)
: '1'
}
onPageChange={this.handlePageChange}
firstItem={{
'aria-label': 'First item',
content: <Icon name='angle double left' />,
key: '1'
}}
prevItem={{
'aria-label': 'Previous item',
content: <Icon name='angle left' />,
key: '4'
}}
nextItem={{
'aria-label': 'Next item',
content: <Icon name='angle right' />,
key: '3'
}}
lastItem={{
'aria-label': 'Last item',
content: <Icon name='angle double right' />,
key: '2'
}}
/>
</BrowserView>
<MobileView>
<Input
type='number'
placeholder={this.props.page['index'] && this.props.page['index']}
style={{ width: '4em' }}
onKeyPress={this.handleKeyPress}
ref={this.handleRef}
/>
{' of '}
{this.props.issueList
? Math.ceil(this.props.issueList['count'] / 10)
: '1'}
</MobileView>
</React.Fragment>
)
}
<>
<div className={tailwindWrapper('flex items-center justify-end p-4')}>
<BrowserView>
<Pagination totalPages={totalPages} activePage={activePage} onPageChange={handlePageChange}/>
</BrowserView>
<MobileView>
<div className={tailwindWrapper('flex items-center')}>
<input
type="number"
placeholder={page.index}
onKeyPress={handleKeyPress}
ref={inputRef}
className={tailwindWrapper('border p-1 text-center focus:outline-none w-14')}
/>
<span className={tailwindWrapper('mx-2')}>
of {Math.ceil(issueList.count / 10)}
</span>
</div>
</MobileView>
</div>
</>
)
}

function mapStateToProps (state) {
return {
whoAmI: state.whoAmI,
issueList: state.issueList,
page: state.paginationIndex,
statusNumbers: state.statusNumbers
}
}
const mapStateToProps = (state) => ({
whoAmI: state.whoAmI,
issueList: state.issueList,
page: state.paginationIndex,
statusNumbers: state.statusNumbers,
})

const mapDispatchToProps = dispatch => {
return {
SetUser: () => {
dispatch(setUser)
},
SetIssueList: (id, status) => {
dispatch(setIssueList(id, status))
},
ChangePage: (index, status) => {
dispatch(changePage(index, status))
},
SetStatusNumbers: () => {
dispatch(setStatusNumbers())
}
}
}
const mapDispatchToProps = (dispatch) => ({
SetUser: () => dispatch(setUser),
SetIssueList: (id, status) => dispatch(setIssueList(id, status)),
ChangePage: (index, status) => dispatch(changePage(index, status)),
SetStatusNumbers: () => dispatch(setStatusNumbers()),
})

export default connect(
mapStateToProps,
mapDispatchToProps
)(TabPagination)
export default connect(mapStateToProps, mapDispatchToProps)(TabPagination)
Loading

0 comments on commit 51e9411

Please sign in to comment.