import isNull from 'lodash/isNull' ; import isUndefined from 'lodash/isUndefined' ; import { useContext , useEffect , useState } from 'react' ; import { useHistory } from 'react-router-dom' ; import API from '../../api' ; import { AppCtx , signOut } from '../../context/AppCtx' ; import { ErrorKind , Package } from '../../types' ; import Loading from '../common/Loading' ; import NoData from '../common/NoData' ; import PackageCard from '../common/PackageCard' ; import Pagination from '../common/Pagination' ; import styles from './StarredPackagesView.module.css' ; interface Props { activePage ? : string ; } const DEFAULT_LIMIT = 10 ; const StarredPackagesView = ( props ) => { const history = useHistory ( ) ; const { dispatch } = useContext ( AppCtx ) ; const [ isLoading , setIsLoading ] = useState ( false ) ; const [ packages , setPackages ] = useState < Package [ ] | undefined > ( undefined ) ; const [ apiError , setApiError ] = useState < string | JSX . Element | null > ( null ) ; const [ activePage , setActivePage ] = useState < number > ( props . activePage ? parseInt ( props . activePage ) : 1 ) ; const calculateOffset = ( pageNumber ? ) : number => { return DEFAULT_LIMIT * ( ( pageNumber || activePage ) - 1 ) ; } ; const [ offset , setOffset ] = useState < number > ( calculateOffset ( ) ) ; const [ total , setTotal ] = useState < number | undefined > ( undefined ) ; const onPageNumberChange = ( pageNumber ) : void => { setOffset ( calculateOffset ( pageNumber ) ) ; setActivePage ( pageNumber ) ; } ; const updatePageNumber = ( ) => { history . replace ( { search : `?page=${ activePage }` , } ) ; } ; const onAuthError = ( ) : void => { dispatch ( signOut ( ) ) ; history . push ( '/?modal=login&redirect=/packages/starred' ) ; } ; async function fetchStarredPackages ( ) { try { setIsLoading ( true ) ; const data = await API . getStarredByUser ( { limit : DEFAULT_LIMIT , offset : offset , } ) ; const total = parseInt ( data . paginationTotalCount ) ; if ( total > 0 && data . items . length === 0 ) { onPageNumberChange ( 1 ) ; } else { setPackages ( data . items ) ; setTotal ( total ) ; } updatePageNumber ( ) ; setApiError ( null ) ; setIsLoading ( false ) ; } catch ( err ) { setIsLoading ( false ) ; if ( err . kind !== ErrorKind . Unauthorized ) { setApiError ( 'An error occurred getting your starred packages, please try again later.' ) ; setPackages ( [ ] ) ; } else { onAuthError ( ) ; } } } useEffect ( ( ) => { fetchStarredPackages ( ) ; } , [ ] ) ; useEffect ( ( ) => { if ( props . activePage && activePage !== parseInt ( props . activePage ) ) { fetchStarredPackages ( ) ; } } , [ activePage ] ) ; return ( < div className = "d-flex flex-column flex-grow-1 position-relative" > { ( isUndefined ( packages ) || isLoading ) && < Loading />} < main role = "main" className = "container-lg px-sm-4 px-lg-0 py-5" > < div className = "flex-grow-1 position-relative" > < div className = "h3 pb-0" > < div className = "d-flex align-items-center justify-content-center" > < div > Your starred packages < /div> < /div> < /div> < div className = { `row mx-auto mt-4 noFocus ${ styles . wrapper }` } role = "list" id = "content" tabIndex = { - 1 } > { ! isUndefined ( packages ) && ( < > { packages . length === 0 ? ( < NoData issuesLinkVisible = { ! isNull ( apiError ) } > { isNull ( apiError ) ? < > You have not starred any package yet < /> : <>{apiError}</ > } < /NoData>) : (<> { packages . map ( ( item ) => ( < PackageCard key = { item . packageId } package = { item } fromStarredPage = { true } / > ) ) } < />)} < />)} < /div> { ! isUndefined ( total ) && ( < div className = "mx-auto" > < Pagination limit = { DEFAULT_LIMIT } offset = { offset } total = { total } active = { activePage } className = "my-5" onChange = { onPageNumberChange } / > < /div>)} < /div> < /main> < /div>); } ; export default StarredPackagesView ;