Created
June 18, 2020 16:23
-
-
Save mrmorris/bac502886db13f3e77278bce553deb80 to your computer and use it in GitHub Desktop.
Sample Project File
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Alert, Input, Row } from 'antd'; | |
import { debounce } from 'lodash'; | |
import React, { useCallback, useState } from 'react'; | |
import { createPaginationContainer, graphql } from 'react-relay'; | |
import PersonCard from 'components/cards/PersonCard'; | |
import FlexGrid from 'components/FlexGrid'; | |
import InfiniteScroller from 'components/InfiniteScroller'; | |
import InnerWrapper from 'components/InnerWrapper'; | |
import WaveStroke from 'components/svgs/WaveStroke'; | |
import FadeTransition from 'components/transitions/FadeTransition'; | |
import IndustryRoleSelect from 'components/IndustryRoleSelect'; | |
import styles from './index.module.css'; | |
const pageSize = 8; | |
const MembersPage = ({ relay, viewer }) => { | |
const { people } = viewer; | |
const empty = people.edges.length === 0; | |
const [loading, setLoading] = useState(false); | |
const [query, setQuery] = useState(null); | |
const [industryRole, setIndustryRole] = useState(null); | |
const refetch = useCallback( | |
(queryString, industryRole) => | |
relay.refetchConnection(pageSize, () => setLoading(false), { | |
filter: { | |
...(industryRole ? { industryRole: { eq: industryRole } } : {}), | |
...(queryString | |
? { | |
or: { | |
email: { contains: queryString }, | |
firstName: { contains: queryString }, | |
jobTitle: { contains: queryString }, | |
lastName: { contains: queryString }, | |
}, | |
} | |
: {}), | |
}, | |
}), | |
[relay] | |
); | |
const onQueryChange = useCallback( | |
debounce(value => { | |
setLoading(true); | |
setQuery(value); | |
refetch(value, industryRole); | |
}, 500), | |
[refetch, industryRole] | |
); | |
return ( | |
<section> | |
<InnerWrapper> | |
<div className={styles.header}> | |
<h1 className={styles.h1}>Gig Life Members</h1> | |
<WaveStroke /> | |
</div> | |
</InnerWrapper> | |
<InnerWrapper mobilePadded> | |
<div className={styles.searchRow}> | |
<Input.Search | |
defaultValue={query} | |
loading={loading} | |
onChange={e => onQueryChange(e.target.value)} | |
onSearch={onQueryChange} | |
placeholder='Search' | |
size='large' | |
className={styles.searchQuery} | |
/> | |
<IndustryRoleSelect | |
emptyLabel='All Member Types' | |
onChange={useCallback( | |
value => { | |
setIndustryRole(value); | |
setLoading(true); | |
refetch(query, value); | |
}, | |
[refetch, query] | |
)} | |
size='large' | |
className={[ | |
'height-adjustable-selector', | |
styles.searchIndustryRole, | |
].join(' ')} | |
value={industryRole} | |
viewer={viewer} | |
/> | |
</div> | |
<InfiniteScroller | |
hasNextPage={relay.hasMore()} | |
loading={loading} | |
onLoadMore={useCallback(() => { | |
if (relay.hasMore() && !relay.isLoading()) { | |
setLoading(true); | |
relay.loadMore(pageSize, () => setLoading(false)); | |
} | |
}, [relay])} | |
> | |
{empty ? ( | |
<FadeTransition> | |
<Row gutter={8} className={styles.row}> | |
<Alert | |
message='No members' | |
description='There are no members for that criteria!' | |
type='info' | |
showIcon | |
/> | |
</Row> | |
</FadeTransition> | |
) : ( | |
<FlexGrid | |
gutter={16} | |
layout={[ | |
[1, 1, 1, 1], | |
]} | |
items={people.edges.map(({ node }) => ( | |
<PersonCard | |
className={styles.row} | |
key={node.id} | |
person={node} | |
span='1' // @todo this is a hacky way to get the title box full width | |
/> | |
))} | |
/> | |
)} | |
</InfiniteScroller> | |
</InnerWrapper> | |
</section> | |
); | |
}; | |
export const MembersPageQuery = graphql` | |
query MembersPageQuery( | |
$after: String | |
$filter: PersonFilterInput | |
$first: Int | |
) { | |
viewer { | |
...MembersPage_viewer | |
@arguments(after: $after, first: $first, filter: $filter) | |
} | |
} | |
`; | |
export default createPaginationContainer( | |
MembersPage, | |
{ | |
viewer: graphql` | |
fragment MembersPage_viewer on Viewer | |
@argumentDefinitions( | |
after: { type: "String" } | |
filter: { type: "PersonFilterInput" } | |
first: { type: "Int", defaultValue: 8 } | |
) { | |
people(after: $after, filter: $filter, first: $first) | |
@connection(key: "MembersPage_people") { | |
edges { | |
node { | |
...PersonCard_person | |
} | |
} | |
} | |
} | |
`, | |
}, | |
{ | |
direction: 'forward', | |
getConnectionFromProps: ({ viewer: { people } }) => people, | |
getFragmentVariables: (prevVars, first) => ({ | |
...prevVars, | |
first, | |
}), | |
getVariables: (props, { count: first, cursor: after }, { filter }) => ({ | |
after, | |
filter, | |
first, | |
}), | |
query: MembersPageQuery, | |
} | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment