Compare commits

..

7 Commits

12 changed files with 325 additions and 215 deletions

2
.env
View File

@ -2,4 +2,4 @@ REACT_APP_KC_URL=https://auth-dev.csi.wmi.amu.edu.pl/
REACT_APP_KC_REALM=gonito-dev
REACT_APP_KC_CLIENT_ID=gonito-dev-localhost
REACT_APP_API=https://gonito.net/api
REACT_APP_API=https://gonito-back-dev.csi.wmi.amu.edu.pl/api

View File

@ -116,7 +116,12 @@ const App = () => {
/>
<Route
path={`${CHALLENGE_PAGE}/:challengeId/howto`}
element={<Challenge section={2} />}
element={
<Challenge
popUpMessageHandler={popUpMessageHandler}
section={2}
/>
}
/>
<Route
path={`${CHALLENGE_PAGE}/:challengeId/myentries`}

View File

@ -1,11 +1,17 @@
import KeyCloakService from '../services/KeyCloakService';
import { API } from '../utils/globals';
const challengeSubmission = (challengeName, repoUrl, repoBranch, description, setLoading) => {
const challengeSubmission = (
challengeName,
repoUrl,
repoBranch,
description,
setLoading
) => {
const details = {
'f1': description,
'f3': repoUrl,
'f4': repoBranch
f1: description,
f3: repoUrl,
f4: repoBranch,
};
let formBody = [];
for (let property in details) {
@ -18,13 +24,15 @@ const challengeSubmission = (challengeName, repoUrl, repoBranch, description, se
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'Authorization': `Bearer ${KeyCloakService.getToken()}`
Authorization: `Bearer ${KeyCloakService.getToken()}`,
},
body: formBody
}).then((resp) => resp.json())
body: formBody,
})
.then((resp) => resp.json())
.then((data) => {
setLoading(true);
window.location.replace(`https://gonito.net/open-view-progress/${data}#form`);
const processUrl = API.replace('/api', '');
window.location.replace(`${processUrl}/open-view-progress/${data}#form`);
});
};

View File

@ -0,0 +1,16 @@
import {API} from '../utils/globals';
import KeyCloakService from '../services/KeyCloakService';
const getFullUser = (setDataState, setLoadingState) => {
fetch(`${API}/full-user-info`, {
headers: {'Authorization': `Bearer ${KeyCloakService.getToken()}`}
})
.then(response => response.json())
.then(data => {
setDataState(data);
if (setLoadingState)
setLoadingState(false);
});
};
export default getFullUser;

View File

@ -8,21 +8,28 @@ import uamLogo from '../../assets/uam-logo.svg';
const Csi = () => {
const mobileRender = () => {
return (
<FlexColumn as='section' alignmentX='flex-start'>
<H2 as='h2' margin='0 0 24px 0'>
Artificial Intelligence Centre (CSI)
<FlexColumn as="section" alignmentX="flex-start">
<H2 as="h2" margin="0 0 24px 0">
Center for Artificial Intelligence (C4AI)
</H2>
<Body as='p' margin='0 0 16px 0'>
<Medium as='span' display='inline'>Gonito.net</Medium> belongs to the
<Medium as='span' display='inline'>&nbsp;Artificial Intelligence Centre (CSI)&nbsp;</Medium>
at Adam Mickiewicz University (UAM) which conducts research on the development of artificial
intelligence, carries out scientific and research and development projects, integrates the research
of scientists from various departments of Adam Mickiewicz University and outside it - from leading
scientific centers in Poland and abroad as well as those employed in business entities.
<Body as="p" margin="0 0 16px 0">
<Medium as="span" display="inline">
Gonito.net
</Medium>{' '}
belongs to the
<Medium as="span" display="inline">
&nbsp;Center for Artificial Intelligence (C4AI)&nbsp;
</Medium>
at Adam Mickiewicz University (UAM) which conducts research on the
development of artificial intelligence, carries out scientific and
research and development projects, integrates the research of
scientists from various departments of Adam Mickiewicz University and
outside it - from leading scientific centers in Poland and abroad as
well as those employed in business entities.
</Body>
<Medium as='p'>
CSI also cooperates with business entities in creating new solutions to be implemented in
enterprises.
<Medium as="p">
C4AI also cooperates with business entities in creating new solutions
to be implemented in enterprises.
</Medium>
</FlexColumn>
);
@ -30,39 +37,40 @@ const Csi = () => {
const desktopRender = () => {
return (
<FlexRow gap='46px'>
<FlexColumn as='section' alignmentX='flex-start' maxWidth='490px'>
<H2 as='h2' margin='0 0 48px 0'>
Artificial Intelligence Centre (CSI)
<FlexRow gap="46px">
<FlexColumn as="section" alignmentX="flex-start" maxWidth="490px">
<H2 as="h2" margin="0 0 48px 0">
Center for Artificial Intelligence (C4AI)
</H2>
<Body as='p' margin='0 0 24px 0'>
<Medium as='span' display='inline'>Gonito.net</Medium> belongs to the
<Medium as='span' display='inline'>&nbsp;Artificial Intelligence Centre (CSI)&nbsp;</Medium>
at Adam Mickiewicz University (UAM) which conducts research on the development of artificial
intelligence, carries out scientific and research and development projects, integrates the
research
of scientists from various departments of Adam Mickiewicz University and outside it - from
leading
scientific centers in Poland and abroad as well as those employed in business entities.
<Body as="p" margin="0 0 24px 0">
<Medium as="span" display="inline">
Gonito.net
</Medium>{' '}
belongs to the
<Medium as="span" display="inline">
&nbsp;Center for Artificial Intelligence (C4AI)&nbsp;
</Medium>
at Adam Mickiewicz University (UAM) which conducts research on the
development of artificial intelligence, carries out scientific and
research and development projects, integrates the research of
scientists from various departments of Adam Mickiewicz University
and outside it - from leading scientific centers in Poland and
abroad as well as those employed in business entities.
</Body>
<Medium as='p'>
CSI also cooperates with business entities in creating new solutions to be implemented in
enterprises.
<Medium as="p">
C4AI also cooperates with business entities in creating new
solutions to be implemented in enterprises.
</Medium>
</FlexColumn>
<Svg src={uamLogo} width='200px' height='242px' size='contain'/>
<Svg src={uamLogo} width="200px" height="242px" size="contain" />
</FlexRow>
);
};
return (
<>
<Media query={theme.mobile}>
{mobileRender()}
</Media>
<Media query={theme.desktop}>
{desktopRender()}
</Media>
<Media query={theme.mobile}>{mobileRender()}</Media>
<Media query={theme.desktop}>{desktopRender()}</Media>
</>
);
};

View File

@ -15,7 +15,7 @@ const CodeShellStyle = styled(FlexColumn)`
border-radius: 4px;
width: 100%;
align-items: flex-start;
max-width: ${({maxWidth}) => maxWidth ? maxWidth : 'none'};
max-width: ${({ maxWidth }) => (maxWidth ? maxWidth : 'none')};
@media (min-width: ${({ theme }) => theme.overMobile}) {
gap: 12px;
@ -40,43 +40,47 @@ const CodeShell = (props) => {
const clickCopyButton = () => {
let commands = '';
if (props.commands.length > 1) {
for (let command of props.commands)
commands += command + '\n';
for (let command of props.commands) commands += command + '\n';
} else commands = props.commands;
navigator.clipboard.writeText(commands).then(r => console.log(r));
navigator.clipboard.writeText(commands).then((r) => console.log(r));
setIco(checkIco);
setTimeout(() => {
setIco(copyIco);
}, 3000);
}, 2000);
};
const formatCommand = (command) => {
if (command[0] === '\t') {
return <>&nbsp;&nbsp;&nbsp;&nbsp;{formatCommand(command.slice(1))}</>;
/* eslint-disable */
} else if (command[0] === '\s') {
return <>&nbsp;{formatCommand(command.slice(1))}</>;
}
return command;
};
const renderCommands = () => {
return props.commands.map((command, index) => {
return (
props.commands.map((command, index) => {
return (
<Code key={`command-${props.codeBlockIndex}-${index}`} as='li'
before={!props.disablePrompt}>
<Code
key={`command-${props.codeBlockIndex}-${index}`}
as="li"
before={!props.disablePrompt}
>
{formatCommand(command)}
</Code>
);
})
);
});
};
return (
<CodeShellStyle as='ul' maxWidth={props.maxWidth}>
<Svg position='absolute' top='12px' right='12px' cursor='pointer'
backgroundColor={theme.colors.white} src={ico} onClick={clickCopyButton}/>
<CodeShellStyle as="ul" maxWidth={props.maxWidth}>
<Svg
position="absolute"
top="12px"
right="12px"
cursor="pointer"
backgroundColor={theme.colors.white}
src={ico}
onClick={clickCopyButton}
/>
{ico === checkIco ? <CopiedMessageStyle>copied!</CopiedMessageStyle> : ''}
{renderCommands()}
</CodeShellStyle>

View File

@ -1,7 +1,7 @@
import React from 'react';
import { Container, FlexColumn, FlexRow, Svg } from '../../utils/containers';
import { useParams } from 'react-router-dom';
import { H1, H2, Medium } from '../../utils/fonts';
import { H1, Medium } from '../../utils/fonts';
import theme from '../../utils/theme';
import MobileChallengeMenu from './MobileChallengeMenu';
import Leaderboard from './Leaderboard/Leaderboard';
@ -48,7 +48,13 @@ const Challenge = (props) => {
/>
);
case 2:
return <HowTo challengeName={challengeName} user={user} />;
return (
<HowTo
popUpMessageHandler={props.popUpMessageHandler}
challengeName={challengeName}
user={user}
/>
);
case 3:
return <MyEntries challengeName={challengeName} />;
case 4:
@ -64,6 +70,7 @@ const Challenge = (props) => {
};
const mobileRender = () => {
if (!loading) {
return (
<FlexColumn
minHeight="100vh"
@ -87,6 +94,9 @@ const Challenge = (props) => {
{sectionRender()}
</FlexColumn>
);
} else {
return <Loading />;
}
};
const desktopRender = () => {
@ -125,19 +135,7 @@ const Challenge = (props) => {
</>
);
} else {
return (
<FlexColumn
position="fixed"
top="0"
left="0"
width="100%"
height="100vh"
zIndex="10"
>
<H2 as="h1">Submission processing...</H2>
<Loading />
</FlexColumn>
);
return <Loading />;
}
};

View File

@ -48,7 +48,7 @@ const DesktopChallengeMenu = (props) => {
<Option
key={`challenge_menu_option-${index}`}
as={Link}
active={index === props.section}
active={index === props.section ? 1 : 0}
to={`/challenge/${props.challengeName}/${options[index]
.toLowerCase()
.replace(' ', '')}`}

View File

@ -1,9 +1,25 @@
import React from 'react';
import getFullUser from '../../../api/getFullUserInfo';
import KeyCloakService from '../../../services/KeyCloakService';
import { FlexColumn } from '../../../utils/containers';
import { IS_MOBILE } from '../../../utils/globals';
import HowToContent from './sections/HowToContent';
const HowTo = (props) => {
const [userFullInfo, setUserFullInfo] = React.useState(null);
React.useEffect(() => {
getFullUser(setUserFullInfo);
if (!KeyCloakService.isLoggedIn()) {
props.popUpMessageHandler(
'Please log in',
'To see everything you must log in',
() => KeyCloakService.doLogin
);
}
}, [props]);
return (
<FlexColumn
margin={IS_MOBILE() ? null : '64px 0 0 0'}
@ -14,6 +30,7 @@ const HowTo = (props) => {
>
<FlexColumn maxWidth="680px" alignmentX="flex-start" gap="48px">
<HowToContent
userFullInfo={userFullInfo}
user={props.user ? props.user : 'yourID'}
challengeName={props.challengeName}
/>

View File

@ -17,6 +17,17 @@ const HowToContent = (props) => {
}
};
const repoKeyRender = () => {
if (props.userFullInfo) {
return (
<CodeShell
codeBlockIndex={0}
commands={[props.userFullInfo.individualKey]}
/>
);
}
};
return (
<FlexColumn
as="article"
@ -36,7 +47,7 @@ const HowToContent = (props) => {
<Body as="p" margin="auto 0">
Create a private git repository with the name
<Medium as="span">&nbsp;{props.challengeName}</Medium>
.&nbsp;The name of the repository must match!
&nbsp;The name of the repository must match!
</Body>
</Grid>
<Grid
@ -46,10 +57,12 @@ const HowToContent = (props) => {
>
<CircleNumber number="2" />
<Body as="p" margin="auto 0">
Add the following ssh key <Medium as="span">REPO_KEY_HERE</Medium> to
your deploy keys in your git repository settings.
Add the following ssh key{' '}
<Medium as="span">{props.userFullInfo ? '' : 'REPO_KEY_HERE'}</Medium>{' '}
to your deploy keys in your git repository settings.
</Body>
</Grid>
{repoKeyRender()}
<Grid
width="100%"
gridTemplateColumns="auto 1fr"

View File

@ -1,15 +1,18 @@
import React from 'react';
import { createPortal } from 'react-dom';
import { FlexColumn } from '../../utils/containers';
import { H2, Menu } from '../../utils/fonts';
import SubmitInput from '../generic/SubmitInput';
import Button from '../generic/Button';
import theme from '../../utils/theme';
import challengeSubmission from '../../api/challengeSubmissionPost';
import Loading from '../generic/Loading';
const Submit = (props) => {
const [description, setDescription] = React.useState('');
const [repoUrl, setRepoUrl] = React.useState('');
const [repoBranch, setRepoBranch] = React.useState('');
const [loading, setLoading] = React.useState(false);
const descriptionHandler = (e) => {
setDescription(e.target.value);
@ -24,27 +27,63 @@ const Submit = (props) => {
};
const challengeSubmissionSubmit = () => {
challengeSubmission(props.challengeName, repoUrl, repoBranch, description, props.setLoading);
};
return (
<FlexColumn margin='40px 0 0 0' padding='24px' as='section' gap='64px' maxWidth='624px' width='100%'
alignmentX='flex-start'>
<H2 as='h2' width='100%' textAlign='center'>
Submit a solution to the challenge
</H2>
<FlexColumn width='100%' gap='32px'>
<SubmitInput label='Submission description' handler={descriptionHandler}/>
<SubmitInput label='Submission repo URL' handler={repoUrlHandler}/>
<SubmitInput label='Submission repo branch' handler={repoBranchHandler}/>
</FlexColumn>
<Button width='122px' height='44px' handler={challengeSubmissionSubmit}>
<Menu color={theme.colors.white}>
Submit
</Menu>
</Button>
</FlexColumn>
setLoading(true);
challengeSubmission(
props.challengeName,
repoUrl,
repoBranch,
description,
setLoading
);
};
if (!loading) {
return (
<FlexColumn
margin="40px 0 0 0"
padding="24px"
as="section"
gap="64px"
maxWidth="624px"
width="100%"
alignmentX="flex-start"
>
<H2 as="h2" width="100%" textAlign="center">
Submit a solution to the challenge
</H2>
<FlexColumn width="100%" gap="32px">
<SubmitInput
label="Submission description"
handler={descriptionHandler}
/>
<SubmitInput label="Submission repo URL" handler={repoUrlHandler} />
<SubmitInput
label="Submission repo branch"
handler={repoBranchHandler}
/>
</FlexColumn>
<Button width="122px" height="44px" handler={challengeSubmissionSubmit}>
<Menu color={theme.colors.white}>Submit</Menu>
</Button>
</FlexColumn>
);
} else {
return createPortal(
<FlexColumn
position="fixed"
top="0"
left="0"
width="100%"
height="100vh"
zIndex="100"
backgroundColor={theme.colors.white}
>
<H2 as="h1">Submission processing...</H2>
<Loading />
</FlexColumn>,
document.body
);
}
};
export default Submit;

View File

@ -76,6 +76,8 @@ const Code = styled(Container)`
line-height: 18px;
font-weight: 300;
color: ${({theme}) => theme.colors.white};
max-width: 600px;
overflow-wrap: break-word;
&:before {
display: ${({before}) => before ? 'inline-block' : 'none'};