basic my entries and some leaderboard corrections

This commit is contained in:
mattyl006 2022-10-19 17:48:04 +02:00
parent 25df7f51a9
commit a77fe19ebc
6 changed files with 299 additions and 72 deletions

View File

@ -4,7 +4,6 @@ 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 {CHALLENGE_PAGE, CHALLENGES_PAGE, IS_MOBILE} 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';
@ -15,6 +14,8 @@ import KeyCloakService from './services/KeyCloakService';
import React from 'react'; import React from 'react';
import LoggedBar from './components/elements/LoggedBar'; import LoggedBar from './components/elements/LoggedBar';
import addUser from './api/addUser'; import addUser from './api/addUser';
import Loading from './components/elements/Loading';
import {FlexColumn} from './utils/containers';
const App = () => { const App = () => {
const [loggedBarVisible, setLoggedBarVisible] = React.useState('100vw'); const [loggedBarVisible, setLoggedBarVisible] = React.useState('100vw');
@ -51,35 +52,53 @@ const App = () => {
setLoggedBarHover(false); setLoggedBarHover(false);
}; };
return ( const renderApp = () => {
<BrowserRouter> return (
<ThemeProvider theme={theme}> <BrowserRouter>
<NavBar loggedBarVisibleHandler={loggedBarVisibleHandler}/> <ThemeProvider theme={theme}>
{!IS_MOBILE() ? <LoggedBar visible={loggedBarVisible} loggedBarVisibleHandler={loggedBarVisibleHandler} <NavBar loggedBarVisibleHandler={loggedBarVisibleHandler}/>
loggedBarHoverTrue={loggedBarHoverTrue} {!IS_MOBILE() ?
loggedBarHoverFalse={loggedBarHoverFalse} <LoggedBar visible={loggedBarVisible} loggedBarVisibleHandler={loggedBarVisibleHandler}
username={KeyCloakService.getUsername()}/> : ''} loggedBarHoverTrue={loggedBarHoverTrue}
<Routes> loggedBarHoverFalse={loggedBarHoverFalse}
<Route path='/register-email' element={<RegisterWithEmail/>}/> username={KeyCloakService.getUsername()}/> : ''}
<Route path='/login-email' element={<LoginWithEmail/>}/> <Routes>
<Route path='/login' element={<Login/>}/> <Route path='/register-email' element={<RegisterWithEmail/>}/>
<Route path='/register' element={<Register/>}/> <Route path='/login-email' element={<LoginWithEmail/>}/>
<Route path={`${CHALLENGE_PAGE}/:challengeId`} element={<Challenge/>}/> <Route path='/login' element={<Login/>}/>
<Route path={CHALLENGES_PAGE} element={<Challenges/>}/> <Route path='/register' element={<Register/>}/>
{ <Route path={`${CHALLENGE_PAGE}/:challengeId`} element={<Challenge/>}/>
KeyCloakService.isLoggedIn() ? <> <Route path={CHALLENGES_PAGE} element={<Challenges/>}/>
<Route exact path='/' element={<Challenges/>}/> {
<Route element={<Challenges/>}/> KeyCloakService.isLoggedIn() ? <>
</> : <> <Route exact path='/' element={<Challenges/>}/>
<Route exact path='/' element={<LandingPage/>}/> <Route element={<Challenges/>}/>
<Route element={<LandingPage/>}/> </> : <>
</> <Route exact path='/' element={<LandingPage/>}/>
} <Route element={<LandingPage/>}/>
</Routes> </>
{/*<Footer/>*/} }
</ThemeProvider> </Routes>
</BrowserRouter> </ThemeProvider>
); </BrowserRouter>
);
};
if (sessionStorage.getItem('logged') === 'yes') {
if (KeyCloakService.isLoggedIn()) {
return renderApp();
} else {
return (
<ThemeProvider theme={theme}>
<FlexColumn width='100vw' height='100vh'>
<Loading/>
</FlexColumn>
</ThemeProvider>
);
}
} else {
return renderApp();
}
}; };
export default App; export default App;

View File

@ -7,10 +7,10 @@ const getMyEntries = (challengeName, setDataState, setLoadingState) => {
}) })
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
console.log(data);
setDataState(data); setDataState(data);
if (setLoadingState) if (setLoadingState)
setLoadingState(false); console.log(data);
setLoadingState(false);
}); });
}; };

View File

@ -20,7 +20,7 @@ const Leaderboard = (props) => {
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(null);
const [sortBy, setSortBy] = React.useState(5); const [sortBy, setSortBy] = React.useState(5);
React.useEffect(() => { React.useEffect(() => {
@ -32,9 +32,19 @@ const Leaderboard = (props) => {
getChallengeLeaderboard(setEntries, challengeName, setLoading); getChallengeLeaderboard(setEntries, challengeName, setLoading);
}; };
const getMainMetricIndex = () => {
let i = 0;
for (let evaluation of entriesFromApi[0].evaluations) {
if (evaluation.test.metric === props.mainMetric) {
return i;
}
i++;
}
};
const renderSubmissions = (gridGap, headerElements) => { const renderSubmissions = (gridGap, headerElements) => {
return _renderSubmissions(pageNr, entries return _renderSubmissions(pageNr, entries
? entries : [], gridGap, metricChoose, sortBy, headerElements); ? entries : [], gridGap, (metricChoose ? metricChoose : getMainMetricIndex()), sortBy, headerElements);
}; };
const tableSearchQueryHandler = (event) => { const tableSearchQueryHandler = (event) => {
@ -119,7 +129,7 @@ const Leaderboard = (props) => {
const desktopRender = () => { const desktopRender = () => {
return ( return (
<FlexColumn padding='24px' as='section' width='100%' maxWidth='800px'> <FlexColumn padding='24px' as='section' width='100%' maxWidth='1000px'>
<H2 as='h2' margin='0 0 32px 0'> <H2 as='h2' margin='0 0 32px 0'>
Leaderboard Leaderboard
</H2> </H2>

View File

@ -18,7 +18,9 @@ const sortBySwitch = (submissions, metricChoose, sortBy) => {
case 0: case 0:
return submissions.sort((a, b) => (a.submitter < b.submitter) ? 1 : ((b.submitter < a.submitter) ? -1 : 0)); return submissions.sort((a, b) => (a.submitter < b.submitter) ? 1 : ((b.submitter < a.submitter) ? -1 : 0));
case 1: case 1:
return submissions.sort((a, b) => a.evaluations[metricChoose].score - b.evaluations[metricChoose].score); if (metricChoose)
return submissions.sort((a, b) => a.evaluations[metricChoose].score - b.evaluations[metricChoose].score);
return submissions;
case 2: case 2:
return submissions.sort((a, b) => a.times - b.times); return submissions.sort((a, b) => a.times - b.times);
case 3: case 3:
@ -27,7 +29,9 @@ const sortBySwitch = (submissions, metricChoose, sortBy) => {
case 4: case 4:
return submissions.sort((a, b) => (a.submitter > b.submitter) ? 1 : ((b.submitter > a.submitter) ? -1 : 0)); return submissions.sort((a, b) => (a.submitter > b.submitter) ? 1 : ((b.submitter > a.submitter) ? -1 : 0));
case 5: case 5:
return submissions.sort((a, b) => b.evaluations[metricChoose].score - a.evaluations[metricChoose].score); if (metricChoose)
return submissions.sort((a, b) => b.evaluations[metricChoose].score - a.evaluations[metricChoose].score);
return submissions;
case 6: case 6:
return submissions.sort((a, b) => b.times - a.times); return submissions.sort((a, b) => b.times - a.times);
case 7: case 7:
@ -65,31 +69,29 @@ const _renderSubmissions = (pageNr, submissions, gridGap, metricChoose, sortBy,
as='td'>{elem}</Medium> as='td'>{elem}</Medium>
); );
}) : ''} }) : ''}
{index > 0 ? <> <Body as='td'>
<Body as='td'> {index + n}
{index + n} </Body>
</Body> <Body as='td'>
<Body as='td'> {submitter ? submitter : '[anonymous]'}
{submitter ? submitter : '[anonymous]'} </Body>
</Body> {!IS_MOBILE() ? evaluations.map((metric, i) => {
{!IS_MOBILE() ? evaluations.map((metric, i) => { return (
return ( <Body key={`metric-result-${i}`} as='td' textAlign='left' minWidth='72px'>
<Body key={`metric-result-${i}`} as='td' textAlign='left' minWidth='72px'> {metric.score.slice(0, 7)}
{metric.score.slice(0, 7)} </Body>
</Body> );
); }) : <Body as='td' textAlign='left' minWidth='72px'>
}) : <Body as='td' textAlign='left' minWidth='72px'> {evaluations[metricChoose] ? evaluations[metricChoose].score.slice(0, 7) : 'xxx'}
{evaluations[metricChoose] ? evaluations[metricChoose].score.slice(0, 7) : 'xxx'} </Body>}
</Body>} <Body as='td' padding='0 2px 0 0' textAlign='right'>
<Body as='td' padding='0 2px 0 0' textAlign='right'> {times ? times : 1}
{times ? times : 1} </Body>
</Body> <Body as='td' textAlign='right'>
<Body as='td' textAlign='right'> {when ? `${when.slice(11, 16)} ${when.slice(0, 10)}`
{when ? `${when.slice(11, 16)} ${when.slice(0, 10)}` : 'xxx'}
: 'xxx'} </Body>
</Body> {index !== 0 ? <Line as='td'/> : ''}
<Line as='td'/>
</> : ''}
</Grid> </Grid>
); );
})} })}

View File

@ -2,33 +2,125 @@ import React from 'react';
import {FlexColumn} from '../../utils/containers'; import {FlexColumn} from '../../utils/containers';
import {H2} from '../../utils/fonts'; import {H2} from '../../utils/fonts';
import getMyEntries from '../../api/getMyEntries'; import getMyEntries from '../../api/getMyEntries';
// import Search from '../elements/Search';
import Table from '../elements/Table';
import Pager from '../elements/Pager';
import {CALC_PAGES} from '../../utils/globals';
import Media from 'react-media';
import theme from '../../utils/theme';
// import sortOptions from './Leaderboard/sortOptions';
// import FilterBy from './FilterBy';
import _tableSearchQueryHandler from './Leaderboard/_tableSearchQueryHandler';
import Loading from '../elements/Loading';
import _renderMySubmissions from './MyEntries/_renderMySubmissions';
const MyEntries = (props) => { const MyEntries = (props) => {
/* eslint-disable */ /* eslint-disable */
const [myEntriesFromAPI, setMyEntriesFromAPI] = React.useState([]); const [myEntriesFromAPI, setMyEntriesFromAPI] = React.useState({});
/* eslint-disable */ /* eslint-disable */
const [myEntries, setMyEntries] = React.useState([]); const [myEntries, setMyEntries] = React.useState({});
/* eslint-disable */ /* eslint-disable */
const [loading, setLoading] = React.useState(true); const [loading, setLoading] = React.useState(true);
const [pageNr, setPageNr] = React.useState(1);
const [metricChoose, setMetricChoose] = React.useState(0);
const [sortBy, setSortBy] = React.useState(5);
React.useEffect(() => { React.useEffect(() => {
challengesRequest(); challengesRequest();
}, []); }, []);
const renderSubmissions = (gridGap, headerElements) => {
return _renderMySubmissions(pageNr, myEntries
? myEntries : [], gridGap, metricChoose, sortBy, headerElements);
};
const tableSearchQueryHandler = (event) => {
_tableSearchQueryHandler(event, myEntriesFromAPI, setPageNr, setMyEntries);
};
const getPossibleMetrics = () => {
let metrics = [];
for (let test of myEntriesFromAPI.tests) {
let myEval = `${test.metric} ${test.name}`;
if (myEval && !metrics.includes(myEval)) {
metrics.push(myEval);
}
}
return metrics;
}
const nextPage = () => {
if (pageNr !== CALC_PAGES(myEntries ? myEntries : [])) {
let newPage = pageNr + 1;
setPageNr(newPage);
}
};
const previousPage = () => {
if (pageNr !== 1) {
let newPage = pageNr - 1;
setPageNr(newPage);
}
};
const getMyEntriesHeader = () => {
let header = ['#'];
for (let myEval of getPossibleMetrics()) {
header.push(myEval);
}
header.push('when');
return header;
};
const challengesRequest = () => { const challengesRequest = () => {
getMyEntries(props.challengeName, setMyEntriesFromAPI); getMyEntries(props.challengeName, setMyEntriesFromAPI);
getMyEntries(props.challengeName, setMyEntries, setLoading); getMyEntries(props.challengeName, setMyEntries, setLoading);
}; };
const sortByHandler = (value) => {
setSortBy(value);
};
const mobileRender = () => {
}
const desktopRender = () => {
if (loading) {
return (
<Loading/>
);
} else {
return (
<FlexColumn padding='24px' as='section' width='100%' maxWidth='1000px'>
<H2 as='h2' margin='0 0 32px 0'>
My entries
</H2>
{/*<Search searchQueryHandler={tableSearchQueryHandler}/>*/}
{/*<FilterBy header='Sort by' options={sortOptions} gridTemplateColumns='auto auto auto auto'*/}
{/* option={sortBy} textAlign='center' margin='32px 0 0 0'*/}
{/* alignmentX='center' handler={sortByHandler}/>*/}
<Table challengeName={props.challengeName} loading={loading}
renderElements={renderSubmissions}
headerElements={getMyEntriesHeader()}/>
<Pager pageNr={pageNr} width='72px' borderRadius='64px'
pages={CALC_PAGES(myEntries.submissions ? myEntries.submissions : [])}
nextPage={nextPage} previousPage={previousPage}
number={`${pageNr} / ${CALC_PAGES(myEntries.submissions ? myEntries.submissions : [])}`}/>
</FlexColumn>
);
}
};
return ( return (
<FlexColumn padding='24px' as='section'> <>
<H2 as='h2'> <Media query={theme.mobile}>
My entries {mobileRender()}
</H2> </Media>
{/*{myEntries.map((entry, index) => {*/} <Media query={theme.desktop}>
{/* */} {desktopRender()}
{/*})}*/} </Media>
</FlexColumn> </>
); );
}; };

View File

@ -0,0 +1,104 @@
import {ELEMENTS_PER_PAGE, IS_MOBILE} from '../../../utils/globals';
import {FlexColumn, FlexRow, Grid} from '../../../utils/containers';
import {Body, Medium} from '../../../utils/fonts';
import styled from 'styled-components';
import React from 'react';
const Line = styled(FlexRow)`
position: absolute;
top: -6px;
left: 0;
width: 100%;
background-color: ${({theme}) => theme.colors.dark04};
height: 1px;
`;
// 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 renderEvalResult = (evaluations, test) => {
for (let myEval of evaluations) {
if (myEval.test.name === test.name && myEval.test.metric === test.metric) {
return myEval.score.slice(0, 7);
}
}
return 'xxx';
};
const _renderMySubmissions = (pageNr, myEntries, gridGap, metricChoose, sortBy, headerElements) => {
const n = (pageNr - 1) * ELEMENTS_PER_PAGE;
if (myEntries) {
// submissions = sortBySwitch(submissions, metricChoose, sortBy);
let submissions = myEntries.submissions.slice(n, n + ELEMENTS_PER_PAGE);
return (
<FlexColumn as='tbody' width='100%'>
{submissions.map(({
submitter,
when,
evaluations,
times,
description
}, index) => {
return (
<Grid as='tr' key={`leaderboard-row-${index}`}
gridTemplateColumns={!IS_MOBILE() ? '1fr ' + '4fr '.repeat(headerElements.length - 2) + '2fr' : '1fr 3fr 1fr 1fr 2fr'}
gridGap={gridGap} margin='10px 0 0 0' position='relative' width='100%' padding='4px'>
{index === 0 ? headerElements.map((elem, i) => {
return (
<Medium key={`leaderboard-header-${i}`}
textAlign={elem === 'entries' || elem === 'when' ? 'right' : 'left'}
minWidth={elem === 'result' ? '72px' : 'none'}
fontSize='18px'
as='td'>{elem}</Medium>
);
}) : ''}
<Body as='td'>
{index + n + 1}
</Body>
{myEntries.tests.map((test, i) => {
console.log(description);
return (
<Body key={`eval-result-${i}`} width='80px' as='td' textAlign='left'
minWidth='72px'>
{renderEvalResult(evaluations, test)}
</Body>
);
})}
<Body as='td' textAlign='right'>
{when ? `${when.slice(11, 16)} ${when.slice(0, 10)}`
: 'xxx'}
</Body>
{index !== 0 ? <Line as='td'/> : ''}
</Grid>
);
})}
</FlexColumn>
);
}
};
export default _renderMySubmissions;