all metrics in Leaderboard on desktop

This commit is contained in:
mattyl006 2022-10-14 14:55:29 +02:00
parent 41fc6e4503
commit 25df7f51a9
6 changed files with 70 additions and 83 deletions

View File

@ -5,7 +5,7 @@ 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, IS_MOBILE} 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';
import Login from './pages/auth/Login'; import Login from './pages/auth/Login';
@ -34,7 +34,7 @@ const App = () => {
KeyCloakService.doLogin(); KeyCloakService.doLogin();
} }
} }
}, 200); }, 500);
}); });
const loggedBarVisibleHandler = () => { const loggedBarVisibleHandler = () => {
@ -55,9 +55,10 @@ const App = () => {
<BrowserRouter> <BrowserRouter>
<ThemeProvider theme={theme}> <ThemeProvider theme={theme}>
<NavBar loggedBarVisibleHandler={loggedBarVisibleHandler}/> <NavBar loggedBarVisibleHandler={loggedBarVisibleHandler}/>
<LoggedBar visible={loggedBarVisible} loggedBarVisibleHandler={loggedBarVisibleHandler} {!IS_MOBILE() ? <LoggedBar visible={loggedBarVisible} loggedBarVisibleHandler={loggedBarVisibleHandler}
loggedBarHoverTrue={loggedBarHoverTrue} loggedBarHoverFalse={loggedBarHoverFalse} loggedBarHoverTrue={loggedBarHoverTrue}
username={KeyCloakService.getUsername()}/> loggedBarHoverFalse={loggedBarHoverFalse}
username={KeyCloakService.getUsername()}/> : ''}
<Routes> <Routes>
<Route path='/register-email' element={<RegisterWithEmail/>}/> <Route path='/register-email' element={<RegisterWithEmail/>}/>
<Route path='/login-email' element={<LoginWithEmail/>}/> <Route path='/login-email' element={<LoginWithEmail/>}/>

View File

@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import {FlexColumn, FlexRow, Grid} from '../../utils/containers'; import {FlexColumn} from '../../utils/containers';
import {H3, Medium} from '../../utils/fonts';
import Media from 'react-media'; import Media from 'react-media';
import theme from '../../utils/theme'; import theme from '../../utils/theme';
import Loading from './Loading'; import Loading from './Loading';
@ -10,37 +9,15 @@ const Table = (props) => {
const mobileRender = () => { const mobileRender = () => {
return ( return (
<FlexColumn as='table' margin='20px 0 32px 0' minHeight='380px'> <FlexColumn as='table' margin='20px 0 32px 0' minHeight='380px'>
<Grid as='thead' gridTemplateColumns='1fr 3fr 1fr 1fr 2fr' {props.renderElements('10px', props.headerElements)}
gridGap='10px' width='100%'>
{props.headerElements.map((elem, index) => {
return (
<FlexRow as='tr' key={`leaderboard-header-${index}`}
alignmentX={(elem === '#' || elem === 'submitter') ? 'flex-start' : 'flex-end'}>
<Medium as='th'>{elem}</Medium>
</FlexRow>
);
})}
</Grid>
{props.renderElements('10px')}
</FlexColumn> </FlexColumn>
); );
}; };
const desktopRender = () => { const desktopRender = () => {
return ( return (
<FlexColumn as='table' margin='32px 0 72px 0' minHeight='438px' width='100%'> <FlexColumn as='table' margin='32px 0 72px 0' width='100%'>
<Grid as='thead' gridTemplateColumns='1fr 3fr 1fr 1fr 2fr' {props.renderElements('32px', props.headerElements)}
gridGap='32px' width='100%' margin='0 0 28px 0'>
{props.headerElements.map((elem, index) => {
return (
<FlexRow as='tr' key={`leaderboard-header-${index}`}
alignmentX={(elem === '#' || elem === 'submitter') ? 'flex-start' : 'flex-end'}>
<H3 as='th'>{elem}</H3>
</FlexRow>
);
})}
</Grid>
{props.renderElements('32px')}
</FlexColumn> </FlexColumn>
); );
}; };

View File

@ -16,7 +16,6 @@ import FilterBy from '../FilterBy';
import sortOptions from './sortOptions'; import sortOptions from './sortOptions';
const Leaderboard = (props) => { const Leaderboard = (props) => {
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);
@ -33,9 +32,9 @@ const Leaderboard = (props) => {
getChallengeLeaderboard(setEntries, challengeName, setLoading); getChallengeLeaderboard(setEntries, challengeName, setLoading);
}; };
const renderSubmissions = (gridGap) => { const renderSubmissions = (gridGap, headerElements) => {
return _renderSubmissions(pageNr, entries return _renderSubmissions(pageNr, entries
? entries : [], gridGap, metricChoose, sortBy); ? entries : [], gridGap, metricChoose, sortBy, headerElements);
}; };
const tableSearchQueryHandler = (event) => { const tableSearchQueryHandler = (event) => {
@ -69,6 +68,16 @@ const Leaderboard = (props) => {
return metrics; return metrics;
}; };
const getLeaderboardHeader = () => {
let header = ['#', 'submitter'];
for (let metric of getPossibleMetrics()) {
header.push(metric);
}
header.push('entries');
header.push('when');
return header;
};
const metricChooseHandler = (value) => { const metricChooseHandler = (value) => {
setMetricChoose(value); setMetricChoose(value);
}; };
@ -98,7 +107,8 @@ const Leaderboard = (props) => {
}) : ''} }) : ''}
</FlexRow> : ''} </FlexRow> : ''}
<Table challengeName={props.challengeName} loading={loading} <Table challengeName={props.challengeName} loading={loading}
renderElements={renderSubmissions} headerElements={headerElements}/> renderElements={renderSubmissions}
headerElements={['#', 'submitter', 'result', 'entries', 'when']}/>
<Pager pageNr={pageNr} width='48px' borderRadius='64px' <Pager pageNr={pageNr} width='48px' borderRadius='64px'
pages={CALC_PAGES(entries ? entries : [])} pages={CALC_PAGES(entries ? entries : [])}
nextPage={nextPage} previousPage={previousPage} nextPage={nextPage} previousPage={previousPage}
@ -114,32 +124,12 @@ const Leaderboard = (props) => {
Leaderboard Leaderboard
</H2> </H2>
<Search searchQueryHandler={tableSearchQueryHandler}/> <Search searchQueryHandler={tableSearchQueryHandler}/>
<FlexRow gap='40px' margin='32px 0'> <FilterBy header='Sort by' options={sortOptions} gridTemplateColumns='auto auto auto auto'
{!loading ? <> option={sortBy} textAlign='center' margin='32px 0 0 0'
<FilterBy header='Sort by' options={sortOptions} gridTemplateColumns='auto auto auto auto' alignmentX='center' handler={sortByHandler}/>
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={getLeaderboardHeader()}/>
<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

@ -1,6 +1,6 @@
import {ELEMENTS_PER_PAGE} from '../../../utils/globals'; import {ELEMENTS_PER_PAGE, IS_MOBILE} from '../../../utils/globals';
import {FlexColumn, FlexRow, Grid} from '../../../utils/containers'; import {FlexColumn, FlexRow, Grid} from '../../../utils/containers';
import {Body} from '../../../utils/fonts'; import {Body, Medium} from '../../../utils/fonts';
import styled from 'styled-components'; import styled from 'styled-components';
const Line = styled(FlexRow)` const Line = styled(FlexRow)`
@ -38,7 +38,7 @@ const sortBySwitch = (submissions, metricChoose, sortBy) => {
} }
}; };
const _renderSubmissions = (pageNr, submissions, gridGap, metricChoose, sortBy) => { const _renderSubmissions = (pageNr, submissions, gridGap, metricChoose, sortBy, headerElements) => {
const n = (pageNr - 1) * ELEMENTS_PER_PAGE; const n = (pageNr - 1) * ELEMENTS_PER_PAGE;
if (submissions) { if (submissions) {
@ -53,25 +53,43 @@ const _renderSubmissions = (pageNr, submissions, gridGap, metricChoose, sortBy)
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={!IS_MOBILE() ? '1fr 3fr ' + '1fr '.repeat(evaluations.length) + '1fr 2fr' : '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'>
<Body as='td'> {index === 0 ? headerElements.map((elem, i) => {
{index + n + 1} return (
</Body> <Medium key={`leaderboard-header-${i}`}
<Body as='td'> textAlign={elem === 'entries' || elem === 'when' ? 'right' : 'left'}
{submitter ? submitter : '[anonymous]'} minWidth={elem === 'result' ? '72px' : 'none'}
</Body> fontSize='18px'
<Body as='td' textAlign='right'> as='td'>{elem}</Medium>
{evaluations[metricChoose] ? evaluations[metricChoose].score : 'xxx'} );
</Body> }) : ''}
<Body as='td' padding='0 2px 0 0' textAlign='right'> {index > 0 ? <>
{times ? times : 1} <Body as='td'>
</Body> {index + n}
<Body as='td' textAlign='right'> </Body>
{when ? `${when.slice(11, 16)} ${when.slice(0, 10)}` <Body as='td'>
: 'xxx'} {submitter ? submitter : '[anonymous]'}
</Body> </Body>
<Line as='td'/> {!IS_MOBILE() ? evaluations.map((metric, i) => {
return (
<Body key={`metric-result-${i}`} as='td' textAlign='left' minWidth='72px'>
{metric.score.slice(0, 7)}
</Body>
);
}) : <Body as='td' textAlign='left' minWidth='72px'>
{evaluations[metricChoose] ? evaluations[metricChoose].score.slice(0, 7) : 'xxx'}
</Body>}
<Body as='td' padding='0 2px 0 0' textAlign='right'>
{times ? times : 1}
</Body>
<Body as='td' textAlign='right'>
{when ? `${when.slice(11, 16)} ${when.slice(0, 10)}`
: 'xxx'}
</Body>
<Line as='td'/>
</> : ''}
</Grid> </Grid>
); );
})} })}

View File

@ -29,7 +29,7 @@ const Challenge = () => {
const sectionRender = () => { const sectionRender = () => {
switch (section) { switch (section) {
case 0: case 0:
return <Leaderboard challengeName={challengeName}/>; return <Leaderboard challengeName={challengeName} mainMetric={challenge.mainMetric}/>;
case 1: case 1:
return <Readme challengeName={challengeName} metric={challenge.mainMetric} return <Readme challengeName={challengeName} metric={challenge.mainMetric}
description={challenge.description} deadline={challenge.deadline}/>; description={challenge.description} deadline={challenge.deadline}/>;
@ -40,7 +40,7 @@ const Challenge = () => {
case 4: case 4:
return <Submit challengeName={challengeName}/>; return <Submit challengeName={challengeName}/>;
default: default:
return <Leaderboard challengeName={challengeName}/>; return <Leaderboard challengeName={challengeName} mainMetric={challenge.mainMetric}/>;
} }
}; };

View File

@ -47,6 +47,7 @@ const Medium = styled(Body)`
font-weight: 400; font-weight: 400;
@media (min-width: ${({theme}) => theme.overMobile}) { @media (min-width: ${({theme}) => theme.overMobile}) {
font-weight: 500; font-weight: 500;
font-size: ${({fontSize}) => fontSize ? fontSize : '16px'}
} }
`; `;