sort by every property in Leaderboard

This commit is contained in:
mattyl006 2022-10-12 18:26:11 +02:00
parent ebbfb8e907
commit 9ac9e742c3
5 changed files with 119 additions and 87 deletions

View File

@ -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>
); );

View File

@ -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>

View File

@ -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'>*/} <Search searchQueryHandler={tableSearchQueryHandler}/>
{/* <BoardVariantDesktop as='button' width='150px' height='48px'*/} <FlexRow gap='40px' margin='32px 0'>
{/* active={0 === variant} onClick={() => setVariant(0)}>*/} <FilterBy header='Sort by' options={sortOptions} gridTemplateColumns='auto auto auto auto'
{/* <H3 as='span'>*/} option={sortBy} textAlign='center'
{/* By user*/} alignmentX='center' handler={sortByHandler}/>
{/* </H3>*/} <FlexColumn gap='32px' as='section'>
{/* </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> <H3>
Metric: Metric
</H3> </H3>
<FlexRow gap='32px'>
{getPossibleMetrics() ? getPossibleMetrics().map((metric, index) => { {getPossibleMetrics() ? getPossibleMetrics().map((metric, index) => {
return ( return (
<Filter option={metricChoose} index={index} borderRadius='4px' width='200px' height='40px' <Filter option={metricChoose} index={index} borderRadius='4px' width='200px'
height='40px'
key={`metric-${index}`} handler={metricChooseHandler} key={`metric-${index}`} handler={metricChooseHandler}
id={`metric-${index}`} name={`metric-${index}`}> id={`metric-${index}`} name={`metric-${index}`}>
{metric} {metric}
</Filter>); </Filter>);
}) : ''} }) : ''}
</FlexRow> </FlexRow>
<Search searchQueryHandler={tableSearchQueryHandler}/> </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}

View File

@ -12,12 +12,41 @@ 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,

View 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;