apply Loading
This commit is contained in:
parent
af7c71a03b
commit
0cd2580957
@ -1,10 +1,12 @@
|
|||||||
import {API} from "../utils/globals";
|
import {API} from "../utils/globals";
|
||||||
|
|
||||||
const getChallengeFullDescription = (setState, challengeName) => {
|
const getChallengeFullDescription = (setDataState, setLoading, challengeName) => {
|
||||||
fetch(`${API}/challenge-readme/${challengeName}/markdown`)
|
fetch(`${API}/challenge-readme/${challengeName}/markdown`)
|
||||||
.then(response => response.text())
|
.then(response => response.text())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
setState(data);
|
setDataState(data);
|
||||||
|
if (setLoading)
|
||||||
|
setLoading(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import {API} from "../utils/globals";
|
import {API} from "../utils/globals";
|
||||||
|
|
||||||
const getChallengeInfo = (setState, challengeName) => {
|
const getChallengeInfo = (setDataState, setLoadingState, challengeName) => {
|
||||||
fetch(`${API}/challenge-info/${challengeName}`)
|
fetch(`${API}/challenge-info/${challengeName}`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
setState(data);
|
setDataState(data);
|
||||||
|
if (setLoadingState)
|
||||||
|
setLoadingState(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import {API} from "../utils/globals";
|
import {API} from "../utils/globals";
|
||||||
|
|
||||||
const getChallengeSubmissions = (setState, challengeName) => {
|
const getChallengeSubmissions = (setDataState, setLoading, challengeName) => {
|
||||||
fetch(`${API}/challenge-all-submissions/${challengeName}`)
|
fetch(`${API}/challenge-all-submissions/${challengeName}`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
setState(data);
|
setDataState(data);
|
||||||
|
if (setLoading)
|
||||||
|
setLoading(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import {API} from "../utils/globals";
|
import {API} from "../utils/globals";
|
||||||
|
|
||||||
const getChallenges = (setState) => {
|
const getChallenges = (setDataState, setLoadingState) => {
|
||||||
fetch(`${API}/list-challenges`)
|
fetch(`${API}/list-challenges`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
setState(data);
|
setDataState(data);
|
||||||
|
if (setLoadingState)
|
||||||
|
setLoadingState(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
50
src/components/elements/Loading.js
Normal file
50
src/components/elements/Loading.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import React from "react";
|
||||||
|
import styled, {keyframes} from "styled-components";
|
||||||
|
import {Container} from "../../utils/containers";
|
||||||
|
|
||||||
|
const rotate = keyframes`
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const SpinnerContainer = styled(Container)`
|
||||||
|
display: grid;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 200px;
|
||||||
|
|
||||||
|
@media (min-width: ${({theme}) => theme.overMobile}) {
|
||||||
|
height: 350px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const LoadingSpinner = styled(Container)`
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border: 10px solid ${({theme}) => theme.colors.dark01}; /* Light grey */
|
||||||
|
border-top: 10px solid ${({theme}) => theme.colors.green}; /* Black */
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: ${rotate} 1.1s ease-in-out infinite;
|
||||||
|
|
||||||
|
@media (min-width: ${({theme}) => theme.overMobile}) {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Loading = (props) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{props.visible ? <SpinnerContainer>
|
||||||
|
<LoadingSpinner/>
|
||||||
|
</SpinnerContainer> : ''}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Loading;
|
@ -49,15 +49,18 @@ const RightArrow = styled(Svg)`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const Pager = (props) => {
|
const Pager = (props) => {
|
||||||
return (
|
if (props.visible) {
|
||||||
<PagerStyle>
|
return (
|
||||||
<LeftArrow as='button' src={polygon} onClick={props.previousPage} size='cover'
|
<PagerStyle>
|
||||||
backgroundColor={(props.pageNr === 1) ? 'transparent' : theme.colors.dark}/>
|
<LeftArrow as='button' src={polygon} onClick={props.previousPage} size='cover'
|
||||||
<CircleNumber number={props.pageNr}/>
|
backgroundColor={(props.pageNr === 1) ? 'transparent' : theme.colors.dark}/>
|
||||||
<RightArrow as='button' src={polygon} onClick={props.nextPage} size='cover'
|
<CircleNumber number={props.pageNr}/>
|
||||||
backgroundColor={(props.pageNr === props.pages) ? 'transparent' : theme.colors.dark}/>
|
<RightArrow as='button' src={polygon} onClick={props.nextPage} size='cover'
|
||||||
</PagerStyle>
|
backgroundColor={(props.pageNr === props.pages) ? 'transparent' : theme.colors.dark}/>
|
||||||
);
|
</PagerStyle>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Pager;
|
export default Pager;
|
@ -7,18 +7,20 @@ import Pager from "../Pager";
|
|||||||
import {CALC_PAGES} from "../../../utils/globals";
|
import {CALC_PAGES} from "../../../utils/globals";
|
||||||
import Media from "react-media";
|
import Media from "react-media";
|
||||||
import theme from "../../../utils/theme";
|
import theme from "../../../utils/theme";
|
||||||
|
import Loading from "../Loading";
|
||||||
|
|
||||||
const Table = (props) => {
|
const Table = (props) => {
|
||||||
const headerElements = ['#', 'submitter', 'when', 'result', 'entries'];
|
const headerElements = ['#', 'submitter', 'when', 'result', 'entries'];
|
||||||
const [challengeData, setChallengeData] = React.useState({});
|
const [challengeData, setChallengeData] = React.useState({});
|
||||||
const [pageNr, setPageNr] = React.useState(1);
|
const [pageNr, setPageNr] = React.useState(1);
|
||||||
|
const [loading, setLoading] = React.useState(true);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
challengeDataRequest();
|
challengeDataRequest();
|
||||||
});
|
});
|
||||||
|
|
||||||
const challengeDataRequest = () => {
|
const challengeDataRequest = () => {
|
||||||
getChallengeSubmissions(setChallengeData, props.challengeName);
|
getChallengeSubmissions(setChallengeData, setLoading, props.challengeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderSubmissions = () => {
|
const renderSubmissions = () => {
|
||||||
@ -54,6 +56,7 @@ const Table = (props) => {
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Loading visible={loading}/>
|
||||||
{renderSubmissions()}
|
{renderSubmissions()}
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
|
|
||||||
@ -74,6 +77,7 @@ const Table = (props) => {
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
<Loading visible={loading}/>
|
||||||
{renderSubmissions()}
|
{renderSubmissions()}
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
);
|
);
|
||||||
@ -87,7 +91,7 @@ const Table = (props) => {
|
|||||||
<Media query={theme.desktop}>
|
<Media query={theme.desktop}>
|
||||||
{desktopRender()}
|
{desktopRender()}
|
||||||
</Media>
|
</Media>
|
||||||
<Pager pageNr={pageNr} nextPage={nextPage} previousPage={previousPage}
|
<Pager visible={!loading} pageNr={pageNr} nextPage={nextPage} previousPage={previousPage}
|
||||||
pages={CALC_PAGES(challengeData.submissions ? challengeData.submissions : [])}/>
|
pages={CALC_PAGES(challengeData.submissions ? challengeData.submissions : [])}/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -7,6 +7,7 @@ import getChallengeFullDescription from "../../api/getChallengeFullDescription";
|
|||||||
import {markdown} from "markdown";
|
import {markdown} from "markdown";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import InfoList from "../elements/InfoList";
|
import InfoList from "../elements/InfoList";
|
||||||
|
import Loading from "../elements/Loading";
|
||||||
|
|
||||||
const ReadmeStyle = styled(Body)`
|
const ReadmeStyle = styled(Body)`
|
||||||
h3 {
|
h3 {
|
||||||
@ -52,9 +53,10 @@ const ReadmeStyle = styled(Body)`
|
|||||||
|
|
||||||
const Readme = (props) => {
|
const Readme = (props) => {
|
||||||
const [fullDescription, setFullDescription] = React.useState('');
|
const [fullDescription, setFullDescription] = React.useState('');
|
||||||
|
const [loading, setLoading] = React.useState(true);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
getChallengeFullDescription(setFullDescription, props.challengeName);
|
getChallengeFullDescription(setFullDescription, setLoading, props.challengeName);
|
||||||
}, [props.challengeName]);
|
}, [props.challengeName]);
|
||||||
|
|
||||||
const parseMarkdownResponse = (response) => {
|
const parseMarkdownResponse = (response) => {
|
||||||
@ -148,10 +150,10 @@ const Readme = (props) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Media query={theme.mobile}>
|
<Media query={theme.mobile}>
|
||||||
{mobileRender()}
|
{!loading ? mobileRender() : <Loading visible={loading}/>}
|
||||||
</Media>
|
</Media>
|
||||||
<Media query={theme.desktop}>
|
<Media query={theme.desktop}>
|
||||||
{desktopRender()}
|
{!loading ? desktopRender() : <Loading visible={loading}/>}
|
||||||
</Media>
|
</Media>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -11,6 +11,7 @@ import theme from "../../utils/theme";
|
|||||||
import cupIco from '../../assets/cup_ico.svg';
|
import cupIco from '../../assets/cup_ico.svg';
|
||||||
import getChallenges from "../../api/getChallenges";
|
import getChallenges from "../../api/getChallenges";
|
||||||
import {CALC_PAGES} from "../../utils/globals";
|
import {CALC_PAGES} from "../../utils/globals";
|
||||||
|
import Loading from "../../components/elements/Loading";
|
||||||
|
|
||||||
const Challenges = () => {
|
const Challenges = () => {
|
||||||
const [pageNr, setPageNr] = React.useState(1);
|
const [pageNr, setPageNr] = React.useState(1);
|
||||||
@ -21,6 +22,7 @@ const Challenges = () => {
|
|||||||
const [status, setStatus] = React.useState(0);
|
const [status, setStatus] = React.useState(0);
|
||||||
const [challengeType, setChallengeType] = React.useState(0);
|
const [challengeType, setChallengeType] = React.useState(0);
|
||||||
const [commercial, setCommercial] = React.useState(0);
|
const [commercial, setCommercial] = React.useState(0);
|
||||||
|
const [loading, setLoading] = React.useState(true);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
challengesRequest();
|
challengesRequest();
|
||||||
@ -28,7 +30,7 @@ const Challenges = () => {
|
|||||||
|
|
||||||
const challengesRequest = () => {
|
const challengesRequest = () => {
|
||||||
getChallenges(setChallengesFromAPI);
|
getChallenges(setChallengesFromAPI);
|
||||||
getChallenges(setChallenges);
|
getChallenges(setChallenges, setLoading);
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortByHandler = (value) => {
|
const sortByHandler = (value) => {
|
||||||
@ -90,10 +92,11 @@ const Challenges = () => {
|
|||||||
</H1>
|
</H1>
|
||||||
<Search searchQueryHandler={searchQueryHandler} toggleFiltersMenu={toggleFiltersMenu}/>
|
<Search searchQueryHandler={searchQueryHandler} toggleFiltersMenu={toggleFiltersMenu}/>
|
||||||
<FlexColumn width='100%'>
|
<FlexColumn width='100%'>
|
||||||
|
<Loading visible={loading}/>
|
||||||
{renderChallenges()}
|
{renderChallenges()}
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
<Pager pageNr={pageNr} pages={CALC_PAGES(challenges)}
|
<Pager visible={!loading} pageNr={pageNr} pages={CALC_PAGES(challenges)}
|
||||||
nextPage={nextPage} previousPage={previousPage}/>
|
nextPage={nextPage} previousPage={previousPage}/>
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
</>
|
</>
|
||||||
@ -124,10 +127,11 @@ const Challenges = () => {
|
|||||||
height='160px' backgroundColor={theme.colors.green}/>
|
height='160px' backgroundColor={theme.colors.green}/>
|
||||||
</FlexRow>
|
</FlexRow>
|
||||||
<FlexColumn width='100%'>
|
<FlexColumn width='100%'>
|
||||||
|
<Loading visible={loading}/>
|
||||||
{renderChallenges()}
|
{renderChallenges()}
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
<Pager pageNr={pageNr} pages={CALC_PAGES(challenges)}
|
<Pager visible={!loading} pageNr={pageNr} pages={CALC_PAGES(challenges)}
|
||||||
nextPage={nextPage} previousPage={previousPage}/>
|
nextPage={nextPage} previousPage={previousPage}/>
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
</>
|
</>
|
||||||
|
@ -20,19 +20,22 @@ const ChallengesGrid = styled(Grid)`
|
|||||||
|
|
||||||
const _renderChallenges = (pageNr, challenges) => {
|
const _renderChallenges = (pageNr, challenges) => {
|
||||||
const n = (pageNr - 1) * ELEMENTS_PER_PAGE;
|
const n = (pageNr - 1) * ELEMENTS_PER_PAGE;
|
||||||
return (
|
if (challenges && challenges !== []) {
|
||||||
<ChallengesGrid margin='32px 0' gridGap='32px 0'>
|
return (
|
||||||
{challenges.slice(n, n + ELEMENTS_PER_PAGE).map((challenge, index) => {
|
<ChallengesGrid margin='32px 0' gridGap='32px 0'>
|
||||||
return (
|
{challenges.slice(n, n + ELEMENTS_PER_PAGE).map((challenge, index) => {
|
||||||
<MiniChallenge key={`challenge-${index}`} title={challenge.title} type={challenge.type}
|
return (
|
||||||
description={challenge.description} metric={challenge.mainMetric}
|
<MiniChallenge key={`challenge-${index}`} title={challenge.title} type={challenge.type}
|
||||||
bestScore={challenge.bestScore} baseline={challenge.baseline}
|
description={challenge.description} metric={challenge.mainMetric}
|
||||||
prize={challenge.prize} deadline={challenge.deadline}
|
bestScore={challenge.bestScore} baseline={challenge.baseline}
|
||||||
name={challenge.name}/>
|
prize={challenge.prize} deadline={challenge.deadline}
|
||||||
);
|
name={challenge.name}/>
|
||||||
})}
|
);
|
||||||
</ChallengesGrid>
|
})}
|
||||||
)
|
</ChallengesGrid>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
export default _renderChallenges;
|
export default _renderChallenges;
|
@ -14,14 +14,16 @@ import DesktopChallengeMenu from "../components/elements/DesktopChallengeMenu";
|
|||||||
import {RENDER_ICO} from "../utils/globals";
|
import {RENDER_ICO} from "../utils/globals";
|
||||||
import textIco from "../assets/text_ico.svg";
|
import textIco from "../assets/text_ico.svg";
|
||||||
import getChallengeInfo from "../api/getChallengeInfo";
|
import getChallengeInfo from "../api/getChallengeInfo";
|
||||||
|
import Loading from "../components/elements/Loading";
|
||||||
|
|
||||||
const Challenge = () => {
|
const Challenge = () => {
|
||||||
const challengeName = useParams().challengeId;
|
const challengeName = useParams().challengeId;
|
||||||
const [challenge, setChallenge] = React.useState([]);
|
const [challenge, setChallenge] = React.useState([]);
|
||||||
const [section, setSection] = React.useState(0);
|
const [section, setSection] = React.useState(0);
|
||||||
|
const [loading, setLoading] = React.useState(true);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
getChallengeInfo(setChallenge, challengeName);
|
getChallengeInfo(setChallenge, setLoading, challengeName);
|
||||||
}, [challengeName]);
|
}, [challengeName]);
|
||||||
|
|
||||||
const sectionRender = () => {
|
const sectionRender = () => {
|
||||||
@ -45,6 +47,7 @@ const Challenge = () => {
|
|||||||
const mobileRender = () => {
|
const mobileRender = () => {
|
||||||
return (
|
return (
|
||||||
<FlexColumn minHeight='100vh' gap='12px' alignmentY='flex-start' padding='66px 0 0 0'>
|
<FlexColumn minHeight='100vh' gap='12px' alignmentY='flex-start' padding='66px 0 0 0'>
|
||||||
|
<Loading visible={loading}/>
|
||||||
<H1 as='h1' margin='0 0 8px 0' textAlign='center'>
|
<H1 as='h1' margin='0 0 8px 0' textAlign='center'>
|
||||||
{challenge.title}
|
{challenge.title}
|
||||||
</H1>
|
</H1>
|
||||||
@ -61,6 +64,7 @@ const Challenge = () => {
|
|||||||
<DesktopChallengeMenu setSection={setSection} section={section}/>
|
<DesktopChallengeMenu setSection={setSection} section={section}/>
|
||||||
<FlexColumn minHeight='100vh' alignmentY='flex-start' padding='64px 0 64px 310px'>
|
<FlexColumn minHeight='100vh' alignmentY='flex-start' padding='64px 0 64px 310px'>
|
||||||
<FlexRow gap='32px' margin='0 0 32px 0' padding='16px'>
|
<FlexRow gap='32px' margin='0 0 32px 0' padding='16px'>
|
||||||
|
<Loading visible={loading}/>
|
||||||
<FlexColumn alignmentX='flex-start' gap='24px' maxWidth='500px'>
|
<FlexColumn alignmentX='flex-start' gap='24px' maxWidth='500px'>
|
||||||
<H1 as='h1'>
|
<H1 as='h1'>
|
||||||
{challenge.title}
|
{challenge.title}
|
||||||
|
@ -4,6 +4,7 @@ const colors = {
|
|||||||
green03: 'rgba(27, 153, 139, 0.3)',
|
green03: 'rgba(27, 153, 139, 0.3)',
|
||||||
green05: 'rgba(27, 153, 139, 0.5)',
|
green05: 'rgba(27, 153, 139, 0.5)',
|
||||||
dark: '#343434',
|
dark: '#343434',
|
||||||
|
dark01: 'rgba(52, 52, 52, 0.1)',
|
||||||
dark03: 'rgba(52, 52, 52, 0.3)',
|
dark03: 'rgba(52, 52, 52, 0.3)',
|
||||||
dark04: 'rgba(52, 52, 52, 0.4)',
|
dark04: 'rgba(52, 52, 52, 0.4)',
|
||||||
dark05: 'rgba(52, 52, 52, 0.5)',
|
dark05: 'rgba(52, 52, 52, 0.5)',
|
||||||
|
Loading…
Reference in New Issue
Block a user