diff --git a/src/App.js b/src/App.js index 6a600d2..f629170 100644 --- a/src/App.js +++ b/src/App.js @@ -148,6 +148,10 @@ const App = () => { path={`${CHALLENGE_PAGE}/:challengeId/submit`} element={} /> + } + /> } /> { + await fetch(`${API}/challenge-all-submissions/${challengeName}`) + .then((response) => response.json()) + .then((data) => { + console.log(data); + setDataState(data.entries); + }); + + if (setLoading) { + setLoading(false); + } +}; + +export default getAllEntries; diff --git a/src/components/specific_challenge/AllEntries/AllEntries.js b/src/components/specific_challenge/AllEntries/AllEntries.js new file mode 100644 index 0000000..d92a584 --- /dev/null +++ b/src/components/specific_challenge/AllEntries/AllEntries.js @@ -0,0 +1,186 @@ +import React from 'react'; +import theme from '../../../utils/theme'; +import Media from 'react-media'; +import { FlexColumn } from '../../../utils/containers'; +import { H2 } from '../../../utils/fonts'; +import { + // CALC_PAGES, + EVALUATIONS_FORMAT, + RENDER_WHEN, +} from '../../../utils/globals'; +import Loading from '../../generic/Loading'; +import Pager from '../../generic/Pager'; +import Table from '../Table'; +import Search from '../../generic/Search'; +import allEntriesSearchQueryHandler from './allEntriesSearchQueryHandler'; +import getAllEntries from '../../../api/getAllEntries'; + +const AllEntries = (props) => { + const [entriesFromApi, setEntriesFromApi] = React.useState([]); + const [entries, setEntries] = React.useState([]); + const [pageNr, setPageNr] = React.useState(1); + const [loading, setLoading] = React.useState(true); + // const [submitterSorted, setSubmitterSorted] = React.useState(false); + // const [entriesSorted, setEntriesSorted] = React.useState(false); + const [whenSorted, setWhenSorted] = React.useState(false); + const [scoresSorted, setScoresSorted] = React.useState([]); + + React.useEffect(() => { + challengeDataRequest(props.challengeName); + }, [props.challengeName]); + + const challengeDataRequest = (challengeName) => { + getAllEntries(setEntriesFromApi, challengeName); + getAllEntries(setEntries, challengeName, setLoading); + }; + + const getPossibleMetrics = () => { + let metrics = []; + // for (let test of entriesFromApi.tests) { + // let myEval = `${test.metric}.${test.name}`; + // if (myEval && !metrics.includes(myEval)) { + // metrics.push(myEval); + // } + // } + return metrics; + }; + + const getAllEntriesHeader = () => { + let header = ['#', 'submitter']; + for (let metric of getPossibleMetrics()) { + header.push(metric); + } + header.push('entries'); + header.push('when'); + return header; + }; + + const searchQueryHandler = (event) => { + allEntriesSearchQueryHandler(event, entriesFromApi, setPageNr, setEntries); + }; + + const nextPage = () => { + // if (pageNr !== CALC_PAGES(entries ? entries : [])) { + // let newPage = pageNr + 1; + // setPageNr(newPage); + // } + }; + + const previousPage = () => { + if (pageNr !== 1) { + let newPage = pageNr - 1; + setPageNr(newPage); + } + }; + + const sortByUpdate = (elem, i) => { + let newEntries = entries; + switch (elem) { + case '#': + 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 = getPossibleMetrics().indexOf(elem); + // eslint-disable-next-line no-case-declarations + let newScoresSorted = scoresSorted; + if (scoresSorted[metricIndex]) { + newEntries = newEntries.sort( + (a, b) => + (b.evaluations ? b.evaluations[elem] : -1) - + (a.evaluations ? a.evaluations[elem] : -1) + ); + newScoresSorted[metricIndex] = false; + setScoresSorted(newScoresSorted); + } else { + newEntries = newEntries.sort( + (a, b) => + (a.evaluations ? a.evaluations[elem] : -1) - + (b.evaluations ? b.evaluations[elem] : -1) + ); + newScoresSorted[metricIndex] = true; + setScoresSorted(newScoresSorted); + } + break; + } + setEntries(newEntries); + }; + + const mobileRender = () => { + return <>; + }; + + const desktopRender = () => { + return ( + +

+ All Entries +

+ {!loading ? ( + <> + + + + + ) : ( + + )} + + ); + }; + return ( + <> + {mobileRender()} + {desktopRender()} + + ); +}; + +export default AllEntries; diff --git a/src/components/specific_challenge/AllEntries/allEntriesSearchQueryHandler.js b/src/components/specific_challenge/AllEntries/allEntriesSearchQueryHandler.js new file mode 100644 index 0000000..4f427b6 --- /dev/null +++ b/src/components/specific_challenge/AllEntries/allEntriesSearchQueryHandler.js @@ -0,0 +1,29 @@ +const allEntriesSearchQueryHandler = ( + event, + entriesFromApi, + setPageNr, + setEntries +) => { + let searchQuery = event.target.value; + let submissionsToRender = []; + setPageNr(1); + if (searchQuery === '') setEntries(entriesFromApi); + else { + for (let entry of entriesFromApi) { + const { id, submitter, when, times } = entry; + let evaluations = ''; + for (let evaluation of entry.evaluations) { + evaluations += ` ${evaluation.score}`; + } + const str = `${id} ${submitter} ${when.slice(11, 16)} ${when.slice( + 0, + 10 + )} ${evaluations} ${times}`; + if (str.toLowerCase().includes(searchQuery.toLowerCase())) + submissionsToRender.push(entry); + } + setEntries(submissionsToRender); + } +}; + +export default allEntriesSearchQueryHandler; diff --git a/src/components/specific_challenge/AllEntries/index.js b/src/components/specific_challenge/AllEntries/index.js new file mode 100644 index 0000000..01070b5 --- /dev/null +++ b/src/components/specific_challenge/AllEntries/index.js @@ -0,0 +1 @@ +export { default } from './AllEntries'; diff --git a/src/components/specific_challenge/Challenge.js b/src/components/specific_challenge/Challenge.js index d4810de..e255ada 100644 --- a/src/components/specific_challenge/Challenge.js +++ b/src/components/specific_challenge/Challenge.js @@ -16,6 +16,7 @@ import textIco from '../../assets/text_ico.svg'; import getChallengeInfo from '../../api/getChallengeInfo'; import Loading from '../generic/Loading'; import getUser from '../../api/getUser'; +import AllEntries from './AllEntries/AllEntries'; const Challenge = (props) => { const challengeName = useParams().challengeId; @@ -59,6 +60,10 @@ const Challenge = (props) => { return ; case 4: return ; + case 5: + return ( + + ); default: return ( { let options = ['Leaderboard', 'Readme', 'How to']; if (KeyCloakService.isLoggedIn()) - options = ['Leaderboard', 'Readme', 'How to', 'My entries', 'Submit']; + options = [ + 'Leaderboard', + 'Readme', + 'How to', + 'My entries', + 'Submit', + 'All entries', + ]; return ( {options.map((option, index) => {