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