diff --git a/src/api/getChallengeLeaderboard.js b/src/api/getChallengeLeaderboard.js
index 75c7612..6b7db90 100644
--- a/src/api/getChallengeLeaderboard.js
+++ b/src/api/getChallengeLeaderboard.js
@@ -5,8 +5,11 @@ const getChallengeLeaderboard = (setDataState, challengeName, setLoading) => {
.then(response => response.json())
.then(data => {
setDataState(data.entries);
- if (setLoading)
- setLoading(false);
+ if (setLoading) {
+ setTimeout(() => {
+ setLoading(false);
+ }, 3000);
+ }
});
};
diff --git a/src/components/elements/Table.js b/src/components/elements/Table.js
index 9ccb6f6..d0d588c 100644
--- a/src/components/elements/Table.js
+++ b/src/components/elements/Table.js
@@ -1,23 +1,103 @@
import React from 'react';
-import {FlexColumn} from '../../utils/containers';
+import {FlexColumn, FlexRow, Grid, Svg} from '../../utils/containers';
import Media from 'react-media';
import theme from '../../utils/theme';
import Loading from './Loading';
import PropsTypes from 'prop-types';
+import {ELEMENTS_PER_PAGE, IS_MOBILE} from '../../utils/globals';
+import {Body, Medium} from '../../utils/fonts';
+import arrow from '../../assets/arrow.svg';
+import styled from 'styled-components';
+
+const Line = styled(FlexRow)`
+ position: absolute;
+ top: ${({top}) => top ? top : 'auto'};
+ bottom: ${({bottom}) => bottom ? bottom : 'auto'};
+ left: 0;
+ width: 100%;
+ background-color: ${({theme}) => theme.colors.dark04};
+ height: ${({height}) => height ? height : '1px'};
+`;
const Table = (props) => {
+ const [, updateState] = React.useState();
+ const forceUpdate = React.useCallback(() => updateState({}), []);
+
const mobileRender = () => {
return (
- {props.renderElements('10px', props.headerElements)}
+ {/*{props.renderElements('10px', props.headerElements)}*/}
);
};
const desktopRender = () => {
+ const n = (props.pageNr - 1) * ELEMENTS_PER_PAGE;
+ let submissionToMap = props.submissions.slice(n, n + ELEMENTS_PER_PAGE);
return (
- {props.renderElements('32px', props.headerElements)}
+
+ {submissionToMap.map(({
+ submitter,
+ when,
+ evaluations,
+ times
+ }, index) => {
+ return (
+
+ {index === 0 ? props.headerElements.map((elem, i) => {
+ return (
+ {
+ props.sortByUpdate(elem);
+ forceUpdate();
+ }}>
+
+ {elem}
+
+ {elem !== '#' ?
+ <>
+
+
+ > : ''}
+
+ );
+ }) : ''}
+ {index === 0 ? : ''}
+
+ {index + n}
+
+
+ {submitter ? submitter : '[anonymous]'}
+
+ {!IS_MOBILE() ? evaluations.map((metric, i) => {
+ return (
+
+ {metric.score.slice(0, 7)}
+
+ );
+ }) :
+ {evaluations[0] ? evaluations[0].score.slice(0, 7) : 'xxx'}
+ }
+
+ {times ? times : 1}
+
+
+ {when ? `${when.slice(11, 16)} ${when.slice(0, 10)}`
+ : 'xxx'}
+
+ {index !== 0 ? : ''}
+
+ );
+ })}
+
);
};
diff --git a/src/components/sections/Leaderboard/Leaderboard.js b/src/components/sections/Leaderboard/Leaderboard.js
index 27938bd..88c9159 100644
--- a/src/components/sections/Leaderboard/Leaderboard.js
+++ b/src/components/sections/Leaderboard/Leaderboard.js
@@ -1,27 +1,25 @@
import React from 'react';
import Media from 'react-media';
import theme from '../../../utils/theme';
-import {FlexColumn, FlexRow} from '../../../utils/containers';
-import {H2, H3} from '../../../utils/fonts';
+import {FlexColumn} from '../../../utils/containers';
+import {H2} from '../../../utils/fonts';
import Table from '../../elements/Table';
import PropsTypes from 'prop-types';
import getChallengeLeaderboard from '../../../api/getChallengeLeaderboard';
-import _renderSubmissions from './_renderSubmissions';
import _tableSearchQueryHandler from './_tableSearchQueryHandler';
import {CALC_PAGES} from '../../../utils/globals';
import Search from '../../elements/Search';
import Pager from '../../elements/Pager';
-import Filter from '../../elements/Filter';
-import FilterBy from '../FilterBy';
-import sortOptions from './sortOptions';
const Leaderboard = (props) => {
const [entriesFromApi, setEntriesFromApi] = React.useState([]);
const [entries, setEntries] = React.useState([]);
const [pageNr, setPageNr] = React.useState(1);
const [loading, setLoading] = React.useState(true);
- const [metricChoose, setMetricChoose] = React.useState(null);
- const [sortBy, setSortBy] = React.useState(5);
+ const [submitterSorted, setSubmitterSorted] = React.useState(false);
+ const [entriesSorted, setEntriesSorted] = React.useState(false);
+ const [whenSorted, setWhenSorted] = React.useState(false);
+ const [scoreSorted, setScoreSorted] = React.useState(false);
React.useEffect(() => {
challengeDataRequest(props.challengeName);
@@ -32,21 +30,16 @@ const Leaderboard = (props) => {
getChallengeLeaderboard(setEntries, challengeName, setLoading);
};
- const getMainMetricIndex = () => {
+ const getMetricIndex = (metricName) => {
let i = 0;
for (let evaluation of entriesFromApi[0].evaluations) {
- if (evaluation.test.metric === props.mainMetric) {
+ if (evaluation.test.metric === metricName) {
return i;
}
i++;
}
};
- const renderSubmissions = (gridGap, headerElements) => {
- return _renderSubmissions(pageNr, entries
- ? entries : [], gridGap, (metricChoose ? metricChoose : getMainMetricIndex()), sortBy, headerElements);
- };
-
const tableSearchQueryHandler = (event) => {
_tableSearchQueryHandler(event, entriesFromApi, setPageNr, setEntries);
};
@@ -88,12 +81,50 @@ const Leaderboard = (props) => {
return header;
};
- const metricChooseHandler = (value) => {
- setMetricChoose(value);
- };
-
- const sortByHandler = (value) => {
- setSortBy(value);
+ const sortByUpdate = (elem) => {
+ let newEntries = entries;
+ console.log(elem);
+ switch (elem) {
+ case 'submitter':
+ if (submitterSorted) {
+ newEntries = newEntries.sort((a, b) => (a.submitter > b.submitter) ? 1 : ((b.submitter > a.submitter) ? -1 : 0));
+ setSubmitterSorted(false);
+ } else {
+ newEntries = newEntries.sort((a, b) => (a.submitter < b.submitter) ? 1 : ((b.submitter < a.submitter) ? -1 : 0));
+ setSubmitterSorted(true);
+ }
+ break;
+ case 'entries':
+ if (entriesSorted) {
+ newEntries = newEntries.sort((a, b) => a.times - b.times);
+ setEntriesSorted(false);
+ } else {
+ newEntries = newEntries.sort((a, b) => b.times - a.times);
+ setEntriesSorted(true);
+ }
+ break;
+ case 'when':
+ if (whenSorted) {
+ newEntries = newEntries.sort((a, b) => (a.when > b.when) ? 1 : ((b.when > a.when) ? -1 : 0));
+ setWhenSorted(false);
+ } else {
+ newEntries = newEntries.sort((a, b) => (a.when < b.when) ? 1 : ((b.when < a.when) ? -1 : 0));
+ setWhenSorted(true);
+ }
+ break;
+ default:
+ // eslint-disable-next-line no-case-declarations
+ let metricIndex = getMetricIndex(elem);
+ if (scoreSorted) {
+ newEntries = newEntries.sort((a, b) => b.evaluations[metricIndex].score - a.evaluations[metricIndex].score);
+ setScoreSorted(false);
+ } else {
+ newEntries = newEntries.sort((a, b) => a.evaluations[metricIndex].score - b.evaluations[metricIndex].score);
+ setScoreSorted(true);
+ }
+ break;
+ }
+ setEntries(newEntries);
};
const mobileRender = () => {
@@ -103,22 +134,9 @@ const Leaderboard = (props) => {
Leaderboard
- {!loading ?
-
- Metric:
-
- {getPossibleMetrics() ? getPossibleMetrics().map((metric, index) => {
- return (
-
- {metric}
- );
- }) : ''}
- : ''}
+ headerElements={['#', 'submitter', 'result', 'entries', 'when']}
+ pageNr={pageNr} submissions={entries} sortByUpdate={sortByUpdate}/>
{
Leaderboard
-
-
+
top ? top : 'auto'};
- bottom: ${({bottom}) => bottom ? bottom : 'auto'};
- left: 0;
- width: 100%;
- background-color: ${({theme}) => theme.colors.dark04};
- height: ${({height}) => height ? 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:
- if (metricChoose)
- return submissions.sort((a, b) => a.evaluations[metricChoose].score - b.evaluations[metricChoose].score);
- return submissions;
- case 2:
- return submissions.sort((a, b) => a.times - b.times);
- case 3:
- 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:
- if (metricChoose)
- return submissions.sort((a, b) => b.evaluations[metricChoose].score - a.evaluations[metricChoose].score);
- return submissions;
- case 6:
- return submissions.sort((a, b) => b.times - a.times);
- case 7:
- 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, headerElements) => {
- const n = (pageNr - 1) * ELEMENTS_PER_PAGE;
-
- if (submissions) {
- submissions = sortBySwitch(submissions, metricChoose, sortBy);
- submissions = submissions.slice(n, n + ELEMENTS_PER_PAGE);
- return (
-
- {submissions.map(({
- submitter,
- when,
- evaluations,
- times
- }, index) => {
- return (
-
- {index === 0 ? headerElements.map((elem, i) => {
- return (
-
-
- {elem}
-
- {elem !== '#' ?
- <>
-
-
- > : ''}
-
- );
- }) : ''}
- {index === 0 ? : ''}
-
- {index + n}
-
-
- {submitter ? submitter : '[anonymous]'}
-
- {!IS_MOBILE() ? evaluations.map((metric, i) => {
- return (
-
- {metric.score.slice(0, 7)}
-
- );
- }) :
- {evaluations[metricChoose] ? evaluations[metricChoose].score.slice(0, 7) : 'xxx'}
- }
-
- {times ? times : 1}
-
-
- {when ? `${when.slice(11, 16)} ${when.slice(0, 10)}`
- : 'xxx'}
-
- {index !== 0 ? : ''}
-
- );
- })}
-
- );
- }
-};
-
-export default _renderSubmissions;
\ No newline at end of file