sort by every property in Leaderboard
This commit is contained in:
parent
ebbfb8e907
commit
9ac9e742c3
@ -4,7 +4,7 @@ import LandingPage from './pages/LandingPage';
|
|||||||
import Challenges from './pages/Challanges/Challenges';
|
import Challenges from './pages/Challanges/Challenges';
|
||||||
import {BrowserRouter, Route, Routes} from 'react-router-dom';
|
import {BrowserRouter, Route, Routes} from 'react-router-dom';
|
||||||
import NavBar from './components/elements/NavBar';
|
import NavBar from './components/elements/NavBar';
|
||||||
import Footer from './components/sections/Footer';
|
// import Footer from './components/sections/Footer';
|
||||||
import {CHALLENGE_PAGE, CHALLENGES_PAGE} from './utils/globals';
|
import {CHALLENGE_PAGE, CHALLENGES_PAGE} from './utils/globals';
|
||||||
import Challenge from './pages/Challenge';
|
import Challenge from './pages/Challenge';
|
||||||
import Register from './pages/auth/Register';
|
import Register from './pages/auth/Register';
|
||||||
@ -58,7 +58,7 @@ const App = () => {
|
|||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</Routes>
|
</Routes>
|
||||||
<Footer/>
|
{/*<Footer/>*/}
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
);
|
);
|
||||||
|
@ -29,18 +29,22 @@ const FilterBy = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlexColumn as='fieldset' width='100%' alignmentX='flex-start' padding='8px'>
|
<FlexColumn as='fieldset' width='100%' padding='8px' margin={props.margin ? props.margin : '0'}
|
||||||
|
alignmentX={props.alignmentX ? props.alignmentX : 'flex-start'}>
|
||||||
<Media query={theme.mobile}>
|
<Media query={theme.mobile}>
|
||||||
<Medium as='legend' textTransform='uppercase' margin='0 0 12px 0'>
|
<Medium as='legend' textTransform='uppercase' margin='0 0 12px 0'>
|
||||||
{props.header}
|
{props.header}
|
||||||
</Medium>
|
</Medium>
|
||||||
</Media>
|
</Media>
|
||||||
<Media query={theme.desktop}>
|
<Media query={theme.desktop}>
|
||||||
<H3 as='legend' textTransform='uppercase' margin='0 0 24px 0'>
|
<H3 as='legend' textTransform='uppercase' width='100%'
|
||||||
|
textAlign={props.textAlign ? props.textAlign : 'left'} margin='0 0 24px 0'>
|
||||||
{props.header}
|
{props.header}
|
||||||
</H3>
|
</H3>
|
||||||
</Media>
|
</Media>
|
||||||
<Grid gridTemplateColumns='auto auto' gridGap='12px' position='relative'>
|
<Grid gridTemplateColumns={props.gridTemplateColumns ? props.gridTemplateColumns : 'auto auto'}
|
||||||
|
gridTemplateRows={props.gridTemplateRows ? props.gridTemplateRows : 'auto'}
|
||||||
|
gridGap='12px' position='relative'>
|
||||||
{renderFilterOptions()}
|
{renderFilterOptions()}
|
||||||
</Grid>
|
</Grid>
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
|
@ -4,7 +4,6 @@ import theme from '../../../utils/theme';
|
|||||||
import {FlexColumn, FlexRow} from '../../../utils/containers';
|
import {FlexColumn, FlexRow} from '../../../utils/containers';
|
||||||
import {H2, H3} from '../../../utils/fonts';
|
import {H2, H3} from '../../../utils/fonts';
|
||||||
import Table from '../../elements/Table';
|
import Table from '../../elements/Table';
|
||||||
// import styled from 'styled-components';
|
|
||||||
import PropsTypes from 'prop-types';
|
import PropsTypes from 'prop-types';
|
||||||
import getChallengeLeaderboard from '../../../api/getChallengeLeaderboard';
|
import getChallengeLeaderboard from '../../../api/getChallengeLeaderboard';
|
||||||
import _renderSubmissions from './_renderSubmissions';
|
import _renderSubmissions from './_renderSubmissions';
|
||||||
@ -13,52 +12,17 @@ import {CALC_PAGES} from '../../../utils/globals';
|
|||||||
import Search from '../../elements/Search';
|
import Search from '../../elements/Search';
|
||||||
import Pager from '../../elements/Pager';
|
import Pager from '../../elements/Pager';
|
||||||
import Filter from '../../elements/Filter';
|
import Filter from '../../elements/Filter';
|
||||||
|
import FilterBy from '../FilterBy';
|
||||||
// const BoardVariantMobile = styled(FlexRow)`
|
import sortOptions from './sortOptions';
|
||||||
// transition: color, background-color 0.3s ease-in-out;
|
|
||||||
// background-color: ${({theme, active}) => active ? theme.colors.dark : theme.colors.white};
|
|
||||||
// color: ${({theme, active}) => active ? theme.colors.white : theme.colors.dark};
|
|
||||||
// font-size: 10px;
|
|
||||||
// font-family: 'Roboto', sans-serif;
|
|
||||||
// font-weight: 300;
|
|
||||||
// border-radius: 16px;
|
|
||||||
// border: 1px solid ${({theme}) => theme.colors.dark};
|
|
||||||
// padding: 6px 8px;
|
|
||||||
// cursor: pointer;
|
|
||||||
// box-shadow: ${({theme}) => theme.shadowRight};
|
|
||||||
//
|
|
||||||
// * {
|
|
||||||
// cursor: pointer;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// &:hover {
|
|
||||||
// background-color: ${({theme, active}) => active ? theme.colors.dark : theme.colors.white};
|
|
||||||
// color: ${({theme, active}) => active ? theme.colors.white : theme.colors.dark};
|
|
||||||
// }
|
|
||||||
// `;
|
|
||||||
|
|
||||||
// const BoardVariantDesktop = styled(FlexRow)`
|
|
||||||
// transition: background-color 0.3s ease-in-out;
|
|
||||||
// border: 1px solid ${({theme}) => theme.colors.green05};
|
|
||||||
// background-color: ${({theme, active}) => active ? theme.colors.green05 : theme.colors.white};
|
|
||||||
//
|
|
||||||
// &:hover {
|
|
||||||
// background-color: ${({theme}) => theme.colors.green05};
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// div {
|
|
||||||
// text-transform: uppercase;
|
|
||||||
// }
|
|
||||||
// `;
|
|
||||||
|
|
||||||
const Leaderboard = (props) => {
|
const Leaderboard = (props) => {
|
||||||
// const [variant, setVariant] = React.useState(0);
|
|
||||||
const headerElements = ['#', 'submitter', 'result', 'entries', 'when'];
|
const headerElements = ['#', 'submitter', 'result', 'entries', 'when'];
|
||||||
const [entriesFromApi, setEntriesFromApi] = React.useState([]);
|
const [entriesFromApi, setEntriesFromApi] = React.useState([]);
|
||||||
const [entries, setEntries] = 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);
|
||||||
const [metricChoose, setMetricChoose] = React.useState(0);
|
const [metricChoose, setMetricChoose] = React.useState(0);
|
||||||
|
const [sortBy, setSortBy] = React.useState(5);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
challengeDataRequest(props.challengeName);
|
challengeDataRequest(props.challengeName);
|
||||||
@ -71,7 +35,7 @@ const Leaderboard = (props) => {
|
|||||||
|
|
||||||
const renderSubmissions = (gridGap) => {
|
const renderSubmissions = (gridGap) => {
|
||||||
return _renderSubmissions(pageNr, entries
|
return _renderSubmissions(pageNr, entries
|
||||||
? entries : [], gridGap, metricChoose);
|
? entries : [], gridGap, metricChoose, sortBy);
|
||||||
};
|
};
|
||||||
|
|
||||||
const tableSearchQueryHandler = (event) => {
|
const tableSearchQueryHandler = (event) => {
|
||||||
@ -109,20 +73,16 @@ const Leaderboard = (props) => {
|
|||||||
setMetricChoose(value);
|
setMetricChoose(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sortByHandler = (value) => {
|
||||||
|
setSortBy(value);
|
||||||
|
};
|
||||||
|
|
||||||
const mobileRender = () => {
|
const mobileRender = () => {
|
||||||
return (
|
return (
|
||||||
<FlexColumn padding='24px 12px' as='section'>
|
<FlexColumn padding='24px 12px' as='section'>
|
||||||
<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 24px 0'>*/}
|
|
||||||
{/* <BoardVariantMobile as='button' active={0 === variant} onClick={() => setVariant(0)}>*/}
|
|
||||||
{/* By user*/}
|
|
||||||
{/* </BoardVariantMobile>*/}
|
|
||||||
{/* <BoardVariantMobile as='button' active={1 === variant} onClick={() => setVariant(1)}>*/}
|
|
||||||
{/* By metric*/}
|
|
||||||
{/* </BoardVariantMobile>*/}
|
|
||||||
{/*</FlexRow>*/}
|
|
||||||
<FlexRow width='100%' gap='16px' as='section' margin='16px 0'>
|
<FlexRow width='100%' gap='16px' as='section' margin='16px 0'>
|
||||||
<H3>
|
<H3>
|
||||||
Metric:
|
Metric:
|
||||||
@ -153,37 +113,32 @@ 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 48px 0'>*/}
|
|
||||||
{/* <BoardVariantDesktop as='button' width='150px' height='48px'*/}
|
|
||||||
{/* active={0 === variant} onClick={() => setVariant(0)}>*/}
|
|
||||||
{/* <H3 as='span'>*/}
|
|
||||||
{/* By user*/}
|
|
||||||
{/* </H3>*/}
|
|
||||||
{/* </BoardVariantDesktop>*/}
|
|
||||||
{/* <BoardVariantDesktop as='button' width='150px' height='48px'*/}
|
|
||||||
{/* active={1 === variant} onClick={() => setVariant(1)}>*/}
|
|
||||||
{/* <H3 as='span'>*/}
|
|
||||||
{/* By metric*/}
|
|
||||||
{/* </H3>*/}
|
|
||||||
{/* </BoardVariantDesktop>*/}
|
|
||||||
{/*</FlexRow>*/}
|
|
||||||
<FlexRow width='100%' gap='32px' as='section' margin='32px 0'>
|
|
||||||
<H3>
|
|
||||||
Metric:
|
|
||||||
</H3>
|
|
||||||
{getPossibleMetrics() ? getPossibleMetrics().map((metric, index) => {
|
|
||||||
return (
|
|
||||||
<Filter option={metricChoose} index={index} borderRadius='4px' width='200px' height='40px'
|
|
||||||
key={`metric-${index}`} handler={metricChooseHandler}
|
|
||||||
id={`metric-${index}`} name={`metric-${index}`}>
|
|
||||||
{metric}
|
|
||||||
</Filter>);
|
|
||||||
}) : ''}
|
|
||||||
</FlexRow>
|
|
||||||
<Search searchQueryHandler={tableSearchQueryHandler}/>
|
<Search searchQueryHandler={tableSearchQueryHandler}/>
|
||||||
|
<FlexRow gap='40px' margin='32px 0'>
|
||||||
|
<FilterBy header='Sort by' options={sortOptions} gridTemplateColumns='auto auto auto auto'
|
||||||
|
option={sortBy} textAlign='center'
|
||||||
|
alignmentX='center' handler={sortByHandler}/>
|
||||||
|
<FlexColumn gap='32px' as='section'>
|
||||||
|
<H3>
|
||||||
|
Metric
|
||||||
|
</H3>
|
||||||
|
<FlexRow gap='32px'>
|
||||||
|
{getPossibleMetrics() ? getPossibleMetrics().map((metric, index) => {
|
||||||
|
return (
|
||||||
|
<Filter option={metricChoose} index={index} borderRadius='4px' width='200px'
|
||||||
|
height='40px'
|
||||||
|
key={`metric-${index}`} handler={metricChooseHandler}
|
||||||
|
id={`metric-${index}`} name={`metric-${index}`}>
|
||||||
|
{metric}
|
||||||
|
</Filter>);
|
||||||
|
}) : ''}
|
||||||
|
</FlexRow>
|
||||||
|
</FlexColumn>
|
||||||
|
</FlexRow>
|
||||||
<Table challengeName={props.challengeName} loading={loading}
|
<Table challengeName={props.challengeName} loading={loading}
|
||||||
renderElements={renderSubmissions}
|
renderElements={renderSubmissions}
|
||||||
headerElements={headerElements}/>
|
headerElements={headerElements}/>
|
||||||
|
|
||||||
<Pager pageNr={pageNr} width='72px' borderRadius='64px'
|
<Pager pageNr={pageNr} width='72px' borderRadius='64px'
|
||||||
pages={CALC_PAGES(entries ? entries : [])}
|
pages={CALC_PAGES(entries ? entries : [])}
|
||||||
nextPage={nextPage} previousPage={previousPage}
|
nextPage={nextPage} previousPage={previousPage}
|
||||||
|
@ -12,17 +12,46 @@ const Line = styled(FlexRow)`
|
|||||||
height: 1px;
|
height: 1px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const _renderSubmissions = (pageNr, submissions, gridGap, metricChoose) => {
|
|
||||||
|
const sortBySwitch = (submissions, metricChoose, sortBy) => {
|
||||||
|
switch (sortBy) {
|
||||||
|
case 0:
|
||||||
|
return submissions.sort((a, b) => (a.submitter < b.submitter) ? 1 : ((b.submitter < a.submitter) ? -1 : 0));
|
||||||
|
case 1:
|
||||||
|
return submissions.sort((a, b) => a.evaluations[metricChoose].score - b.evaluations[metricChoose].score);
|
||||||
|
case 2:
|
||||||
|
return submissions.sort((a, b) => a.times - b.times);
|
||||||
|
case 3:
|
||||||
|
console.log(submissions[0].when);
|
||||||
|
return submissions.sort((a, b) => (a.when > b.when) ? 1 : ((b.when > a.when) ? -1 : 0));
|
||||||
|
case 4:
|
||||||
|
return submissions.sort((a, b) => (a.submitter > b.submitter) ? 1 : ((b.submitter > a.submitter) ? -1 : 0));
|
||||||
|
case 5:
|
||||||
|
return submissions.sort((a, b) => b.evaluations[metricChoose].score - a.evaluations[metricChoose].score);
|
||||||
|
case 6:
|
||||||
|
return submissions.sort((a, b) => b.times - a.times);
|
||||||
|
case 7:
|
||||||
|
console.log(submissions[0].when);
|
||||||
|
return submissions.sort((a, b) => (a.when < b.when) ? 1 : ((b.when < a.when) ? -1 : 0));
|
||||||
|
default:
|
||||||
|
return submissions.sort((a, b) => b.evaluations[metricChoose].score - a.evaluations[metricChoose].score);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const _renderSubmissions = (pageNr, submissions, gridGap, metricChoose, sortBy) => {
|
||||||
const n = (pageNr - 1) * ELEMENTS_PER_PAGE;
|
const n = (pageNr - 1) * ELEMENTS_PER_PAGE;
|
||||||
|
|
||||||
if (submissions) {
|
if (submissions) {
|
||||||
|
submissions = sortBySwitch(submissions, metricChoose, sortBy);
|
||||||
|
submissions = submissions.slice(n, n + ELEMENTS_PER_PAGE);
|
||||||
return (
|
return (
|
||||||
<FlexColumn as='tbody' width='100%'>
|
<FlexColumn as='tbody' width='100%'>
|
||||||
{submissions.slice(n, n + ELEMENTS_PER_PAGE).sort((a, b) => b.evaluations[metricChoose].score - a.evaluations[metricChoose].score).map(({
|
{submissions.map(({
|
||||||
submitter,
|
submitter,
|
||||||
when,
|
when,
|
||||||
evaluations,
|
evaluations,
|
||||||
times
|
times
|
||||||
}, index) => {
|
}, index) => {
|
||||||
return (
|
return (
|
||||||
<Grid as='tr' key={`leaderboard-row-${index}`} gridTemplateColumns='1fr 3fr 1fr 1fr 2fr'
|
<Grid as='tr' key={`leaderboard-row-${index}`} gridTemplateColumns='1fr 3fr 1fr 1fr 2fr'
|
||||||
gridGap={gridGap} margin='10px 0 0 0' position='relative' width='100%' padding='4px'>
|
gridGap={gridGap} margin='10px 0 0 0' position='relative' width='100%' padding='4px'>
|
||||||
|
44
src/components/sections/Leaderboard/sortOptions.js
Normal file
44
src/components/sections/Leaderboard/sortOptions.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
const sortOptions = [
|
||||||
|
{
|
||||||
|
name: 'Submitter',
|
||||||
|
sort: true,
|
||||||
|
rotate: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Result',
|
||||||
|
sort: true,
|
||||||
|
rotate: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Entries',
|
||||||
|
sort: true,
|
||||||
|
rotate: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'When',
|
||||||
|
sort: true,
|
||||||
|
rotate: ''
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Submitter',
|
||||||
|
sort: true,
|
||||||
|
rotate: '180deg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Result',
|
||||||
|
sort: true,
|
||||||
|
rotate: '180deg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Entries',
|
||||||
|
sort: true,
|
||||||
|
rotate: '180deg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'When',
|
||||||
|
sort: true,
|
||||||
|
rotate: '180deg'
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default sortOptions;
|
Loading…
Reference in New Issue
Block a user