Search in Leaderboard
This commit is contained in:
parent
033ef57bbe
commit
6b183ad5bb
@ -1,10 +1,10 @@
|
||||
import {API} from '../utils/globals';
|
||||
|
||||
const getChallengeLeaderboard = (setDataState, setLoading, challengeName) => {
|
||||
const getChallengeLeaderboard = (setDataState, challengeName, setLoading) => {
|
||||
fetch(`${API}/leaderboard/${challengeName}`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
setDataState(data);
|
||||
setDataState(data.entries);
|
||||
if (setLoading)
|
||||
setLoading(false);
|
||||
});
|
||||
|
@ -71,7 +71,7 @@ const FiltersMenu = (props) => {
|
||||
</FlexRow>
|
||||
</Media>
|
||||
<Media query={theme.desktop}>
|
||||
<FlexRow margin='20px 0 0 0' width='94%' alignmentX='flex-start'>
|
||||
<FlexRow margin='8px 0 0 0' width='94%' alignmentX='flex-start'>
|
||||
<Button width='72px' height='34px' backgroundColor={theme.colors.green} handler={resetHandler}>
|
||||
Reset
|
||||
</Button>
|
||||
|
@ -50,23 +50,19 @@ const RightArrow = styled(Svg)`
|
||||
`;
|
||||
|
||||
const Pager = (props) => {
|
||||
if (props.visible) {
|
||||
return (
|
||||
<PagerStyle>
|
||||
<LeftArrow as='button' src={polygon} onClick={props.previousPage} size='cover'
|
||||
backgroundColor={(props.pageNr === 1) ? 'transparent' : theme.colors.dark}/>
|
||||
<CircleNumber number={props.number} width={props.width} borderRadius={props.borderRadius}/>
|
||||
<RightArrow as='button' src={polygon} onClick={props.nextPage} size='cover'
|
||||
backgroundColor={(props.pageNr === props.pages)
|
||||
? 'transparent' : theme.colors.dark}/>
|
||||
</PagerStyle>
|
||||
);
|
||||
}
|
||||
return '';
|
||||
return (
|
||||
<PagerStyle>
|
||||
<LeftArrow as='button' src={polygon} onClick={props.previousPage} size='cover'
|
||||
backgroundColor={(props.pageNr === 1) ? 'transparent' : theme.colors.dark}/>
|
||||
<CircleNumber number={props.number} width={props.width} borderRadius={props.borderRadius}/>
|
||||
<RightArrow as='button' src={polygon} onClick={props.nextPage} size='cover'
|
||||
backgroundColor={(props.pageNr === props.pages)
|
||||
? 'transparent' : theme.colors.dark}/>
|
||||
</PagerStyle>
|
||||
);
|
||||
};
|
||||
|
||||
Pager.propTypes = {
|
||||
visible: PropsTypes.bool,
|
||||
previousPage: PropsTypes.func,
|
||||
pageNr: PropsTypes.number,
|
||||
nextPage: PropsTypes.func,
|
||||
@ -77,7 +73,6 @@ Pager.propTypes = {
|
||||
};
|
||||
|
||||
Pager.defaultProps = {
|
||||
visible: false,
|
||||
previousPage: null,
|
||||
pageNr: 1,
|
||||
nextPage: null,
|
||||
|
@ -29,10 +29,6 @@ const SearchStyle = styled(FlexRow)`
|
||||
&:hover {
|
||||
transform: scale(1.25);
|
||||
}
|
||||
|
||||
@media (min-width: ${({theme}) => theme.overMobile}) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
@ -46,7 +42,8 @@ const Search = (props) => {
|
||||
<SearchStyle>
|
||||
<Svg src={loopIco}/>
|
||||
<Body as='input' onChange={(event) => props.searchQueryHandler(event)}/>
|
||||
<Svg as='button' src={filtersIco} onClick={props.toggleFiltersMenu}/>
|
||||
<Svg as='button' src={filtersIco} onClick={props.toggleFiltersMenu}
|
||||
display={props.filterButton ? 'block' : 'none'}/>
|
||||
</SearchStyle>
|
||||
);
|
||||
};
|
||||
@ -54,11 +51,13 @@ const Search = (props) => {
|
||||
Search.propTypes = {
|
||||
searchQueryHandler: PropsTypes.func,
|
||||
toggleFiltersMenu: PropsTypes.func,
|
||||
filterButton: PropsTypes.bool
|
||||
};
|
||||
|
||||
Search.defaultProps = {
|
||||
searchQueryHandler: null,
|
||||
toggleFiltersMenu: null,
|
||||
filterButton: false,
|
||||
};
|
||||
|
||||
export default Search;
|
@ -9,28 +9,36 @@ import Media from 'react-media';
|
||||
import theme from '../../../utils/theme';
|
||||
import Loading from '../Loading';
|
||||
import PropsTypes from 'prop-types';
|
||||
import _tableSearchQueryHandler from './_tableSearchQueryHandler';
|
||||
import Search from '../Search';
|
||||
|
||||
const Table = (props) => {
|
||||
const headerElements = ['#', 'submitter', 'when', 'result', 'entries'];
|
||||
const [leaderboardData, setLeaderboardData] = React.useState({});
|
||||
const [entriesFromApi, setEntriesFromApi] = React.useState([]);
|
||||
const [entries, setEntries] = React.useState([]);
|
||||
const [pageNr, setPageNr] = React.useState(1);
|
||||
const [loading, setLoading] = React.useState(true);
|
||||
|
||||
React.useEffect(() => {
|
||||
challengeDataRequest();
|
||||
});
|
||||
challengeDataRequest(props.challengeName);
|
||||
}, [props.challengeName]);
|
||||
|
||||
const challengeDataRequest = () => {
|
||||
getChallengeLeaderboard(setLeaderboardData, setLoading, props.challengeName);
|
||||
const challengeDataRequest = (challengeName) => {
|
||||
getChallengeLeaderboard(setEntriesFromApi, challengeName);
|
||||
getChallengeLeaderboard(setEntries, challengeName, setLoading);
|
||||
};
|
||||
|
||||
const renderSubmissions = () => {
|
||||
return _renderSubmissions(pageNr, leaderboardData.entries
|
||||
? leaderboardData.entries : []);
|
||||
return _renderSubmissions(pageNr, entries
|
||||
? entries : []);
|
||||
};
|
||||
|
||||
const tableSearchQueryHandler = (event) => {
|
||||
_tableSearchQueryHandler(event, entriesFromApi, setPageNr, setEntries);
|
||||
};
|
||||
|
||||
const nextPage = () => {
|
||||
if (pageNr !== CALC_PAGES(leaderboardData.entries ? leaderboardData.entries : [])) {
|
||||
if (pageNr !== CALC_PAGES(entries ? entries : [])) {
|
||||
let newPage = pageNr + 1;
|
||||
setPageNr(newPage);
|
||||
}
|
||||
@ -45,40 +53,54 @@ const Table = (props) => {
|
||||
|
||||
const mobileRender = () => {
|
||||
return (
|
||||
<FlexColumn as='table' margin='0 0 32px 0' minHeight='380px'>
|
||||
<Grid as='thead' gridTemplateColumns='1fr 3fr 3fr 1fr 1fr'
|
||||
gridGap='10px' width='100%'>
|
||||
{headerElements.map((elem, index) => {
|
||||
return (
|
||||
<FlexRow as='tr' key={`leaderboard-header-${index}`}
|
||||
alignmentX={elem === 'entries' ? 'flex-end' : 'flex-start'}>
|
||||
<Medium as='th'>{elem}</Medium>
|
||||
</FlexRow>
|
||||
);
|
||||
})}
|
||||
</Grid>
|
||||
{renderSubmissions()}
|
||||
</FlexColumn>
|
||||
|
||||
<>
|
||||
<Search searchQueryHandler={tableSearchQueryHandler}/>
|
||||
<FlexColumn as='table' margin='20px 0 32px 0' minHeight='380px'>
|
||||
<Grid as='thead' gridTemplateColumns='1fr 3fr 3fr 1fr 1fr'
|
||||
gridGap='10px' width='100%'>
|
||||
{headerElements.map((elem, index) => {
|
||||
return (
|
||||
<FlexRow as='tr' key={`leaderboard-header-${index}`}
|
||||
alignmentX={elem === 'entries' ? 'flex-end' : 'flex-start'}>
|
||||
<Medium as='th'>{elem}</Medium>
|
||||
</FlexRow>
|
||||
);
|
||||
})}
|
||||
</Grid>
|
||||
{renderSubmissions()}
|
||||
</FlexColumn>
|
||||
<Pager pageNr={pageNr} width='48px' borderRadius='64px'
|
||||
pages={CALC_PAGES(entries ? entries : [])}
|
||||
nextPage={nextPage} previousPage={previousPage}
|
||||
number={`${pageNr} / ${CALC_PAGES(entries ? entries : [])}`}/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const desktopRender = () => {
|
||||
return (
|
||||
<FlexColumn as='table' margin='0 0 72px 0' minHeight='438px'>
|
||||
<Grid as='thead' gridTemplateColumns='1fr 3fr 3fr 1fr 1fr'
|
||||
gridGap='10px' width='100%' margin='0 0 28px 0'>
|
||||
{headerElements.map((elem, index) => {
|
||||
return (
|
||||
<FlexRow as='tr' key={`leaderboard-header-${index}`}
|
||||
alignmentX={elem === 'entries' ? 'flex-end' : 'flex-start'}>
|
||||
<H3 as='th'>{elem}</H3>
|
||||
</FlexRow>
|
||||
);
|
||||
})}
|
||||
</Grid>
|
||||
{renderSubmissions()}
|
||||
</FlexColumn>
|
||||
<>
|
||||
<Search searchQueryHandler={tableSearchQueryHandler}/>
|
||||
<FlexColumn as='table' margin='32px 0 72px 0' minHeight='438px'>
|
||||
<Grid as='thead' gridTemplateColumns='1fr 3fr 3fr 1fr 1fr'
|
||||
gridGap='10px' width='100%' margin='0 0 28px 0'>
|
||||
{headerElements.map((elem, index) => {
|
||||
return (
|
||||
<FlexRow as='tr' key={`leaderboard-header-${index}`}
|
||||
alignmentX={elem === 'entries' ? 'flex-end' : 'flex-start'}>
|
||||
<H3 as='th'>{elem}</H3>
|
||||
</FlexRow>
|
||||
);
|
||||
})}
|
||||
</Grid>
|
||||
{renderSubmissions()}
|
||||
</FlexColumn>
|
||||
<Pager pageNr={pageNr} width='72px' borderRadius='64px'
|
||||
pages={CALC_PAGES(entries ? entries : [])}
|
||||
nextPage={nextPage} previousPage={previousPage}
|
||||
number={`${pageNr} / ${CALC_PAGES(entries ? entries : [])}`}/>
|
||||
</>
|
||||
|
||||
);
|
||||
};
|
||||
|
||||
@ -86,24 +108,11 @@ const Table = (props) => {
|
||||
<>
|
||||
<Loading visible={loading}/>
|
||||
<Media query={theme.mobile}>
|
||||
<>
|
||||
{!loading ? mobileRender() : ''}
|
||||
<Pager visible={!loading} pageNr={pageNr}
|
||||
pages={CALC_PAGES(leaderboardData.entries ? leaderboardData.entries : [])}
|
||||
nextPage={nextPage} previousPage={previousPage} width='48px' borderRadius='64px'
|
||||
number={`${pageNr} / ${CALC_PAGES(leaderboardData.entries ?
|
||||
leaderboardData.entries : [])}`}/>
|
||||
</>
|
||||
{!loading ? mobileRender() : ''}
|
||||
|
||||
</Media>
|
||||
<Media query={theme.desktop}>
|
||||
<>
|
||||
{!loading ? desktopRender() : ''}
|
||||
<Pager visible={!loading} pageNr={pageNr}
|
||||
pages={CALC_PAGES(leaderboardData.entries ? leaderboardData.entries : [])}
|
||||
nextPage={nextPage} previousPage={previousPage} width='72px' borderRadius='64px'
|
||||
number={`${pageNr} / ${CALC_PAGES(leaderboardData.entries ?
|
||||
leaderboardData.entries : [])}`}/>
|
||||
</>
|
||||
{!loading ? desktopRender() : ''}
|
||||
</Media>
|
||||
</>
|
||||
);
|
||||
|
18
src/components/elements/Table/_tableSearchQueryHandler.js
Normal file
18
src/components/elements/Table/_tableSearchQueryHandler.js
Normal file
@ -0,0 +1,18 @@
|
||||
const _tableSearchQueryHandler = (event, entriesFromApi, setPageNr, setEntries) => {
|
||||
let searchQuery = event.target.value;
|
||||
let submissionsToRender = [];
|
||||
setPageNr(1);
|
||||
if (searchQuery === '')
|
||||
setEntries(entriesFromApi);
|
||||
else {
|
||||
for (let entry of entriesFromApi) {
|
||||
const {submitter, when, evaluations, times} = entry;
|
||||
const str = `${submitter} ${when.slice(11, 16)} ${when.slice(0, 10)} ${evaluations} ${times}`;
|
||||
if (str.toLowerCase().includes(searchQuery.toLowerCase()))
|
||||
submissionsToRender.push(entry);
|
||||
}
|
||||
setEntries(submissionsToRender);
|
||||
}
|
||||
};
|
||||
|
||||
export default _tableSearchQueryHandler;
|
@ -53,7 +53,7 @@ const Leaderboard = (props) => {
|
||||
<H2 as='h2' margin='0 0 12px 0'>
|
||||
Leaderboard
|
||||
</H2>
|
||||
<FlexRow gap='12px' margin='0 0 20px 0'>
|
||||
<FlexRow gap='12px' margin='0 0 24px 0'>
|
||||
<BoardVariantMobile as='button' active={0 === variant} onClick={() => setVariant(0)}>
|
||||
By user
|
||||
</BoardVariantMobile>
|
||||
@ -72,7 +72,7 @@ const Leaderboard = (props) => {
|
||||
<H2 as='h2' margin='0 0 32px 0'>
|
||||
Leaderboard
|
||||
</H2>
|
||||
<FlexRow border={`1px solid ${theme.colors.green05}`} margin='0 0 76px 0'>
|
||||
<FlexRow border={`1px solid ${theme.colors.green05}`} margin='0 0 48px 0'>
|
||||
<BoardVariantDesktop as='button' width='150px' height='48px'
|
||||
active={0 === variant} onClick={() => setVariant(0)}>
|
||||
<H3 as='span'>
|
||||
|
@ -90,15 +90,16 @@ const Challenges = () => {
|
||||
<H1 as='h1' margin='0 0 20px 0'>
|
||||
Challenges
|
||||
</H1>
|
||||
<Search searchQueryHandler={searchQueryHandler} toggleFiltersMenu={toggleFiltersMenu}/>
|
||||
<Search searchQueryHandler={searchQueryHandler} filterButton
|
||||
toggleFiltersMenu={toggleFiltersMenu}/>
|
||||
<FlexColumn width='100%'>
|
||||
<Loading visible={loading}/>
|
||||
{renderChallenges()}
|
||||
</FlexColumn>
|
||||
</FlexColumn>
|
||||
<Pager visible={!loading} pageNr={pageNr} pages={CALC_PAGES(challenges)}
|
||||
nextPage={nextPage} previousPage={previousPage} width='48px' borderRadius='64px'
|
||||
number={`${pageNr} / ${CALC_PAGES(challenges)}`}/>
|
||||
{!loading ? <Pager pageNr={pageNr} pages={CALC_PAGES(challenges)}
|
||||
nextPage={nextPage} previousPage={previousPage} width='48px' borderRadius='64px'
|
||||
number={`${pageNr} / ${CALC_PAGES(challenges)}`}/> : ''}
|
||||
</FlexColumn>
|
||||
</>
|
||||
);
|
||||
@ -122,7 +123,7 @@ const Challenges = () => {
|
||||
<Body margin='0 0 12px 0' maxWidth='400px'>
|
||||
Increase your machine learning skills by competing in our exciting challenges.
|
||||
</Body>
|
||||
<Search searchQueryHandler={searchQueryHandler} toggleFiltersMenu={toggleFiltersMenu}/>
|
||||
<Search searchQueryHandler={searchQueryHandler}/>
|
||||
</FlexColumn>
|
||||
<Svg src={cupIco} size='contain' width='25%'
|
||||
height='160px' backgroundColor={theme.colors.green}/>
|
||||
@ -132,9 +133,9 @@ const Challenges = () => {
|
||||
{renderChallenges()}
|
||||
</FlexColumn>
|
||||
</FlexColumn>
|
||||
<Pager visible={!loading} pageNr={pageNr} pages={CALC_PAGES(challenges)}
|
||||
nextPage={nextPage} previousPage={previousPage} width='72px' borderRadius='64px'
|
||||
number={`${pageNr} / ${CALC_PAGES(challenges)}`}/>
|
||||
{!loading ? <Pager pageNr={pageNr} pages={CALC_PAGES(challenges)}
|
||||
nextPage={nextPage} previousPage={previousPage} width='72px' borderRadius='64px'
|
||||
number={`${pageNr} / ${CALC_PAGES(challenges)}`}/> : ''}
|
||||
</FlexColumn>
|
||||
</>
|
||||
);
|
||||
|
@ -6,8 +6,9 @@ const _searchQueryHandler = (event, challengesFromAPI, setPageNr, setChallenges)
|
||||
setChallenges(challengesFromAPI);
|
||||
else {
|
||||
for (let challenge of challengesFromAPI) {
|
||||
let str = `${challenge.title} ${challenge.description} ${challenge.type} ${challenge.mainMetric}
|
||||
${challenge.bestScore} ${challenge.deadline} ${challenge.baseline} ${challenge.prize}`;
|
||||
const {title, description, type, mainMetric, bestScore, deadline, baseline, prize} = challenge;
|
||||
const str = `${title} ${description} ${type} ${mainMetric} ${bestScore}
|
||||
${deadline.slice(11, 16)} ${deadline.slice(0, 10)} ${baseline} ${prize}`;
|
||||
if (str.toLowerCase().includes(searchQuery.toLowerCase()))
|
||||
challengesToRender.push(challenge);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user