Compare commits
5 Commits
9e9cd81a54
...
9458061f29
Author | SHA1 | Date | |
---|---|---|---|
9458061f29 | |||
ce92499528 | |||
ea33a44326 | |||
6270a6f194 | |||
1464bc084a |
@ -21,7 +21,7 @@ import Loading from './components/generic/Loading';
|
|||||||
import { FlexColumn } from './utils/containers';
|
import { FlexColumn } from './utils/containers';
|
||||||
import PopupMessage from './components/generic/PopupMessage';
|
import PopupMessage from './components/generic/PopupMessage';
|
||||||
import PolicyPrivacy from './pages/PolicyPrivacy';
|
import PolicyPrivacy from './pages/PolicyPrivacy';
|
||||||
import Challenge from './components/specific_challenge/Challenge';
|
import Challenge from './pages/Challenge';
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const [loggedBarVisible, setLoggedBarVisible] = React.useState('100vw');
|
const [loggedBarVisible, setLoggedBarVisible] = React.useState('100vw');
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import KeyCloakService from '../services/KeyCloakService';
|
import KeyCloakService from '../services/KeyCloakService';
|
||||||
import { API } from '../utils/globals';
|
import { API } from '../utils/globals';
|
||||||
|
import SUBMIT_ACTION from '../pages/Submit/model/SubmitActionEnum';
|
||||||
|
|
||||||
const challengeSubmission = (
|
const challengeSubmission = (
|
||||||
challengeName,
|
challengeName,
|
||||||
repoUrl,
|
repoUrl,
|
||||||
repoBranch,
|
repoBranch,
|
||||||
description,
|
description,
|
||||||
setLoading
|
dispatch
|
||||||
) => {
|
) => {
|
||||||
const details = {
|
const details = {
|
||||||
f1: description,
|
f1: description,
|
||||||
@ -30,7 +31,7 @@ const challengeSubmission = (
|
|||||||
})
|
})
|
||||||
.then((resp) => resp.json())
|
.then((resp) => resp.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
setLoading(true);
|
dispatch({ type: SUBMIT_ACTION.TOGGLE_SUBMISSION_LOADING });
|
||||||
const processUrl = API.replace('/api', '');
|
const processUrl = API.replace('/api', '');
|
||||||
window.location.replace(`${processUrl}/open-view-progress/${data}#form`);
|
window.location.replace(`${processUrl}/open-view-progress/${data}#form`);
|
||||||
// console.log(data);
|
// console.log(data);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import CHALLENGES_ACTION from '../pages/Challanges/model/ChallengesActionEnum';
|
import CHALLENGES_ACTION from '../pages/Challanges/model/ChallengesActions';
|
||||||
import { API } from '../utils/globals';
|
import { API } from '../utils/globals';
|
||||||
|
|
||||||
const getChallenges = (dispatch) => {
|
const getChallenges = (dispatch) => {
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
|
import SUBMIT_ACTION from '../pages/Submit/model/SubmitActionEnum';
|
||||||
import { API } from '../utils/globals';
|
import { API } from '../utils/globals';
|
||||||
|
|
||||||
const getTags = (setTags) => {
|
const getTags = (dispatch) => {
|
||||||
fetch(`${API}/list-tags`)
|
fetch(`${API}/list-tags`)
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
setTags(data);
|
dispatch({ type: SUBMIT_ACTION.LOAD_TAGS, payload: data });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,122 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import {Container, FlexColumn, FlexRow, Grid} from '../../utils/containers';
|
|
||||||
import {Body, H3} from '../../utils/fonts';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
import IconLabel from '../generic/IconLabel';
|
|
||||||
import {Link} from 'react-router-dom';
|
|
||||||
import {CHALLENGE_PAGE, MINI_DESCRIPTION_RENDER} from '../../utils/globals';
|
|
||||||
import theme from '../../utils/theme';
|
|
||||||
import PropsTypes from 'prop-types';
|
|
||||||
|
|
||||||
const ChallengeStyle = styled(FlexColumn)`
|
|
||||||
padding: 12px;
|
|
||||||
border: 1px solid ${({theme}) => theme.colors.dark05};
|
|
||||||
cursor: pointer;
|
|
||||||
transition: transform 0.3s ease-in-out;
|
|
||||||
position: relative;
|
|
||||||
max-width: 420px;
|
|
||||||
|
|
||||||
* {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
transform: scale(1.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
article {
|
|
||||||
width: 100%;
|
|
||||||
align-items: flex-start;
|
|
||||||
|
|
||||||
p {
|
|
||||||
width: 80%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: ${({theme}) => theme.overMobile}) {
|
|
||||||
width: 360px;
|
|
||||||
padding: 20px;
|
|
||||||
justify-content: flex-start;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const IconsGrid = styled(Grid)`
|
|
||||||
width: 100%;
|
|
||||||
grid-gap: 14px;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
grid-template-rows: 1fr 1fr;
|
|
||||||
|
|
||||||
@media (min-width: 500px) {
|
|
||||||
grid-template-columns: auto auto auto;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const MiniChallenge = (props) => {
|
|
||||||
const deadlineRender = () => {
|
|
||||||
if (props.deadline) {
|
|
||||||
return (
|
|
||||||
<IconLabel size='24px' gap='8px' type='deadline' time={props.deadline}>
|
|
||||||
{props.deadline.slice(0, 10)}
|
|
||||||
</IconLabel>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ChallengeStyle as={Link} to={`${CHALLENGE_PAGE}/${props.name}`}>
|
|
||||||
<FlexColumn as='article'>
|
|
||||||
<FlexRow margin='0 0 14px 0' gap='12px' width='100%' alignmentX='space-between'>
|
|
||||||
<H3 as='h3' width='85%'>
|
|
||||||
{props.title}
|
|
||||||
</H3>
|
|
||||||
{props.type ? <IconLabel type={props.type} size='30px'/> : 'xxx'}
|
|
||||||
</FlexRow>
|
|
||||||
<Container margin='0 0 14px 0' width='85%' height='1px' backgroundColor={theme.colors.dark05}/>
|
|
||||||
<Body as='p' margin='0 0 14px 0'>
|
|
||||||
{props.description ? MINI_DESCRIPTION_RENDER(props.description) : 'xxx'}
|
|
||||||
</Body>
|
|
||||||
<IconsGrid>
|
|
||||||
<IconLabel size='24px' gap='8px' type='metric'>
|
|
||||||
{props.metric ? props.metric : 'xxx'}
|
|
||||||
</IconLabel>
|
|
||||||
<IconLabel size='24px' gap='8px' type='bestScore'>
|
|
||||||
{props.bestScore ? props.bestScore : 'xxx'}
|
|
||||||
</IconLabel>
|
|
||||||
{deadlineRender()}
|
|
||||||
<IconLabel size='24px' gap='8px' type='baseline'>
|
|
||||||
{props.baseline ? props.baseline : 'xxx'}
|
|
||||||
</IconLabel>
|
|
||||||
{props.prize ? <IconLabel size='24px' gap='8px' type='prize'>
|
|
||||||
{props.prize}
|
|
||||||
</IconLabel> : ''}
|
|
||||||
</IconsGrid>
|
|
||||||
</FlexColumn>
|
|
||||||
</ChallengeStyle>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
MiniChallenge.propTypes = {
|
|
||||||
name: PropsTypes.string,
|
|
||||||
title: PropsTypes.string,
|
|
||||||
type: PropsTypes.string,
|
|
||||||
description: PropsTypes.string,
|
|
||||||
metric: PropsTypes.string,
|
|
||||||
bestScore: PropsTypes.string,
|
|
||||||
deadline: PropsTypes.string,
|
|
||||||
baseline: PropsTypes.string,
|
|
||||||
prize: PropsTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
MiniChallenge.defaultProps = {
|
|
||||||
name: 'xxx',
|
|
||||||
title: 'xxx',
|
|
||||||
type: 'xxx',
|
|
||||||
description: 'xxx',
|
|
||||||
metric: 'xxx',
|
|
||||||
bestScore: 'xxx',
|
|
||||||
deadline: 'xxx',
|
|
||||||
baseline: 'xxx',
|
|
||||||
prize: 'xxx'
|
|
||||||
};
|
|
||||||
|
|
||||||
export default MiniChallenge;
|
|
@ -33,6 +33,7 @@ const Button = (props) => {
|
|||||||
onClick={() => props.handler()}
|
onClick={() => props.handler()}
|
||||||
width={props.width}
|
width={props.width}
|
||||||
height={props.height}
|
height={props.height}
|
||||||
|
margin={props.margin}
|
||||||
color={props.color}
|
color={props.color}
|
||||||
backgroundColor={props.backgroundColor}
|
backgroundColor={props.backgroundColor}
|
||||||
to={props.to}
|
to={props.to}
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { FlexColumn, FlexRow, Grid } from '../../utils/containers';
|
|
||||||
import { Medium } from '../../utils/fonts';
|
|
||||||
import theme from '../../utils/theme';
|
|
||||||
import ImageButton from './ImageButton';
|
|
||||||
import pencilIco from '../../assets/pencil_ico.svg';
|
|
||||||
import styled from 'styled-components';
|
|
||||||
import PopUp from './PopUp';
|
|
||||||
import { createPortal } from 'react-dom';
|
|
||||||
|
|
||||||
const DropdownWithPopupStyle = styled(FlexColumn)`
|
|
||||||
cursor: pointer;
|
|
||||||
gap: 8px;
|
|
||||||
width: 100%;
|
|
||||||
align-items: flex-start;
|
|
||||||
* {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const DropdownWithPopup = (props) => {
|
|
||||||
const [tagsPopUp, setTagsPopUp] = React.useState(false);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DropdownWithPopupStyle
|
|
||||||
onClick={() => {
|
|
||||||
if (!tagsPopUp) setTagsPopUp(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Medium as="label" htmlFor={props.label}>
|
|
||||||
{props.label}
|
|
||||||
</Medium>
|
|
||||||
<Grid
|
|
||||||
borderRadius="4px"
|
|
||||||
width="100%"
|
|
||||||
height="100px"
|
|
||||||
border={`1px solid ${theme.colors.dark}`}
|
|
||||||
shadow={theme.shadow}
|
|
||||||
onChange={(e) => props.handler(e.target.value)}
|
|
||||||
padding="12px"
|
|
||||||
gridTemplateColumns="1fr auto"
|
|
||||||
>
|
|
||||||
<FlexRow height="100%" alignmentX="flex-start" alignmentY="flex-start">
|
|
||||||
dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa
|
|
||||||
dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa
|
|
||||||
dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa
|
|
||||||
dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa dsa
|
|
||||||
</FlexRow>
|
|
||||||
<ImageButton src={pencilIco} width="20px" height="20px" />
|
|
||||||
</Grid>
|
|
||||||
{tagsPopUp &&
|
|
||||||
createPortal(
|
|
||||||
<PopUp closeHandler={() => setTagsPopUp(false)}></PopUp>,
|
|
||||||
document.body
|
|
||||||
)}
|
|
||||||
</DropdownWithPopupStyle>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DropdownWithPopup;
|
|
@ -13,10 +13,13 @@ const PopUpStyle = styled(FlexColumn)`
|
|||||||
|
|
||||||
.PopUpStyle__body {
|
.PopUpStyle__body {
|
||||||
width: ${({ width }) => (width ? width : '60%')};
|
width: ${({ width }) => (width ? width : '60%')};
|
||||||
|
height: ${({ height }) => (height ? height : '50%')};
|
||||||
min-height: ${({ minHeight }) => (minHeight ? minHeight : '50%')};
|
min-height: ${({ minHeight }) => (minHeight ? minHeight : '50%')};
|
||||||
padding: ${({ padding }) => (padding ? padding : '48px')};
|
padding: ${({ padding }) => (padding ? padding : '48px')};
|
||||||
|
margin: ${({ margin }) => (margin ? margin : '0')};
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
background-color: ${({ theme }) => theme.colors.white};
|
background-color: ${({ theme }) => theme.colors.white};
|
||||||
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -31,7 +34,9 @@ const PopUp = (props) => {
|
|||||||
<PopUpStyle
|
<PopUpStyle
|
||||||
padding={props.padding}
|
padding={props.padding}
|
||||||
width={props.width}
|
width={props.width}
|
||||||
|
height={props.height}
|
||||||
minHeight={props.minHeight}
|
minHeight={props.minHeight}
|
||||||
|
margin={props.margin}
|
||||||
onClick={closePopUp}
|
onClick={closePopUp}
|
||||||
>
|
>
|
||||||
<FlexColumn
|
<FlexColumn
|
||||||
|
@ -1,20 +1,20 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import theme from '../../../utils/theme';
|
import theme from '../../utils/theme';
|
||||||
import Media from 'react-media';
|
import Media from 'react-media';
|
||||||
import { FlexColumn } from '../../../utils/containers';
|
import { FlexColumn } from '../../utils/containers';
|
||||||
import { H2 } from '../../../utils/fonts';
|
import { H2 } from '../../utils/fonts';
|
||||||
import {
|
import {
|
||||||
CALC_PAGES,
|
CALC_PAGES,
|
||||||
EVALUATIONS_FORMAT,
|
EVALUATIONS_FORMAT,
|
||||||
RENDER_WHEN,
|
RENDER_WHEN,
|
||||||
IS_MOBILE,
|
IS_MOBILE,
|
||||||
} from '../../../utils/globals';
|
} from '../../utils/globals';
|
||||||
import Loading from '../../generic/Loading';
|
import Loading from '../../components/generic/Loading';
|
||||||
import Pager from '../../generic/Pager';
|
import Pager from '../../components/generic/Pager';
|
||||||
import Table from '../Table';
|
import Table from '../../components/generic/Table';
|
||||||
import Search from '../../generic/Search';
|
import Search from '../../components/generic/Search';
|
||||||
import allEntriesSearchQueryHandler from './allEntriesSearchQueryHandler';
|
import allEntriesSearchQueryHandler from './allEntriesSearchQueryHandler';
|
||||||
import getAllEntries from '../../../api/getAllEntries';
|
import getAllEntries from '../../api/getAllEntries';
|
||||||
|
|
||||||
const AllEntries = (props) => {
|
const AllEntries = (props) => {
|
||||||
const [entriesFromApi, setEntriesFromApi] = React.useState([]);
|
const [entriesFromApi, setEntriesFromApi] = React.useState([]);
|
@ -3,13 +3,13 @@ import Media from 'react-media';
|
|||||||
import theme from '../../utils/theme';
|
import theme from '../../utils/theme';
|
||||||
import getChallenges from '../../api/getChallenges';
|
import getChallenges from '../../api/getChallenges';
|
||||||
import { CHALLENGES_STATUS_FILTER } from '../../utils/globals';
|
import { CHALLENGES_STATUS_FILTER } from '../../utils/globals';
|
||||||
import FiltersMenu from '../../components/challenges_list/FiltersMenu';
|
import FiltersMenu from './components/FiltersMenu';
|
||||||
import statusFilterHandle from './functions/statusFilterHandle';
|
import statusFilterHandle from './functions/statusFilterHandle';
|
||||||
import ChallengesMobile from './components/ChallengesMobile';
|
import ChallengesMobile from './components/ChallengesMobile';
|
||||||
import ChallengesDesktop from './components/ChallengesDesktop';
|
import ChallengesDesktop from './components/ChallengesDesktop';
|
||||||
import challengeSearchQueryHandler from './functions/challengeSearchQueryHandler';
|
import challengeSearchQueryHandler from './functions/challengeSearchQueryHandler';
|
||||||
import ChallengesReducer from './model/ChallengesReducer';
|
import ChallengesReducer from './model/ChallengesReducer';
|
||||||
import CHALLENGES_ACTION from './model/ChallengesActionEnum';
|
import CHALLENGES_ACTION from './model/ChallengesActions';
|
||||||
|
|
||||||
const Challenges = () => {
|
const Challenges = () => {
|
||||||
const [state, dispatch] = React.useReducer(ChallengesReducer, {
|
const [state, dispatch] = React.useReducer(ChallengesReducer, {
|
||||||
|
@ -7,7 +7,7 @@ import Search from '../../../components/generic/Search';
|
|||||||
import { CALC_PAGES } from '../../../utils/globals';
|
import { CALC_PAGES } from '../../../utils/globals';
|
||||||
import renderChallenges from '../functions/renderChallenges';
|
import renderChallenges from '../functions/renderChallenges';
|
||||||
import Loading from '../../../components/generic/Loading';
|
import Loading from '../../../components/generic/Loading';
|
||||||
import CHALLENGES_ACTION from '../model/ChallengesActionEnum';
|
import CHALLENGES_ACTION from '../model/ChallengesActions';
|
||||||
|
|
||||||
const ChallengesMobile = (props) => {
|
const ChallengesMobile = (props) => {
|
||||||
return (
|
return (
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FlexColumn, Grid, Svg } from '../../utils/containers';
|
import { FlexColumn, Grid, Svg } from '../../../utils/containers';
|
||||||
import Filter from '../generic/Filter';
|
import Filter from '../../../components/generic/Filter';
|
||||||
import { Body, H3, Medium } from '../../utils/fonts';
|
import { Body, H3, Medium } from '../../../utils/fonts';
|
||||||
import arrow from '../../assets/arrow.svg';
|
import arrow from '../../../assets/arrow.svg';
|
||||||
import Media from 'react-media';
|
import Media from 'react-media';
|
||||||
import theme from '../../utils/theme';
|
import theme from '../../../utils/theme';
|
||||||
|
|
||||||
const FilterBy = (props) => {
|
const FilterBy = (props) => {
|
||||||
const renderFilterOptions = () => {
|
const renderFilterOptions = () => {
|
@ -1,12 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FlexColumn, FlexRow, TransBack } from '../../../utils/containers';
|
import { FlexColumn, FlexRow, TransBack } from '../../../../utils/containers';
|
||||||
import Button from '../../generic/Button';
|
import Button from '../../../../components/generic/Button';
|
||||||
import theme from '../../../utils/theme';
|
import theme from '../../../../utils/theme';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import FilterBy from '../FilterBy';
|
import FilterBy from '../FilterBy';
|
||||||
import filterOptions from './filterOptions';
|
import filterOptions from './filterOptions';
|
||||||
import Media from 'react-media';
|
import Media from 'react-media';
|
||||||
import CHALLENGES_ACTION from '../../../pages/Challanges/model/ChallengesActionEnum';
|
import CHALLENGES_ACTION from '../../model/ChallengesActions';
|
||||||
|
|
||||||
const FiltersMenuStyle = styled(FlexColumn)`
|
const FiltersMenuStyle = styled(FlexColumn)`
|
||||||
position: fixed;
|
position: fixed;
|
121
src/pages/Challanges/components/MiniChallenge.js
Normal file
121
src/pages/Challanges/components/MiniChallenge.js
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Container,
|
||||||
|
FlexColumn,
|
||||||
|
FlexRow,
|
||||||
|
Grid,
|
||||||
|
} from '../../../utils/containers';
|
||||||
|
import { Body, H3 } from '../../../utils/fonts';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import IconLabel from '../../../components/generic/IconLabel';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import {
|
||||||
|
CHALLENGE_PAGE,
|
||||||
|
MINI_DESCRIPTION_RENDER,
|
||||||
|
} from '../../../utils/globals';
|
||||||
|
import theme from '../../../utils/theme';
|
||||||
|
|
||||||
|
const ChallengeStyle = styled(FlexColumn)`
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid ${({ theme }) => theme.colors.dark05};
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.3s ease-in-out;
|
||||||
|
position: relative;
|
||||||
|
max-width: 420px;
|
||||||
|
|
||||||
|
* {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
article {
|
||||||
|
width: 100%;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
p {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: ${({ theme }) => theme.overMobile}) {
|
||||||
|
width: 360px;
|
||||||
|
padding: 20px;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const IconsGrid = styled(Grid)`
|
||||||
|
width: 100%;
|
||||||
|
grid-gap: 14px;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
grid-template-rows: 1fr 1fr;
|
||||||
|
|
||||||
|
@media (min-width: 500px) {
|
||||||
|
grid-template-columns: auto auto auto;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MiniChallenge = (props) => {
|
||||||
|
const deadlineRender = () => {
|
||||||
|
if (props.deadline) {
|
||||||
|
return (
|
||||||
|
<IconLabel size="24px" gap="8px" type="deadline" time={props.deadline}>
|
||||||
|
{props.deadline.slice(0, 10)}
|
||||||
|
</IconLabel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ChallengeStyle as={Link} to={`${CHALLENGE_PAGE}/${props.name}`}>
|
||||||
|
<FlexColumn as="article">
|
||||||
|
<FlexRow
|
||||||
|
margin="0 0 14px 0"
|
||||||
|
gap="12px"
|
||||||
|
width="100%"
|
||||||
|
alignmentX="space-between"
|
||||||
|
>
|
||||||
|
<H3 as="h3" width="85%">
|
||||||
|
{props.title}
|
||||||
|
</H3>
|
||||||
|
{props.type ? <IconLabel type={props.type} size="30px" /> : 'xxx'}
|
||||||
|
</FlexRow>
|
||||||
|
<Container
|
||||||
|
margin="0 0 14px 0"
|
||||||
|
width="85%"
|
||||||
|
height="1px"
|
||||||
|
backgroundColor={theme.colors.dark05}
|
||||||
|
/>
|
||||||
|
<Body as="p" margin="0 0 14px 0">
|
||||||
|
{props.description
|
||||||
|
? MINI_DESCRIPTION_RENDER(props.description)
|
||||||
|
: 'xxx'}
|
||||||
|
</Body>
|
||||||
|
<IconsGrid>
|
||||||
|
<IconLabel size="24px" gap="8px" type="metric">
|
||||||
|
{props.metric ? props.metric : 'xxx'}
|
||||||
|
</IconLabel>
|
||||||
|
<IconLabel size="24px" gap="8px" type="bestScore">
|
||||||
|
{props.bestScore ? props.bestScore : 'xxx'}
|
||||||
|
</IconLabel>
|
||||||
|
{deadlineRender()}
|
||||||
|
<IconLabel size="24px" gap="8px" type="baseline">
|
||||||
|
{props.baseline ? props.baseline : 'xxx'}
|
||||||
|
</IconLabel>
|
||||||
|
{props.prize ? (
|
||||||
|
<IconLabel size="24px" gap="8px" type="prize">
|
||||||
|
{props.prize}
|
||||||
|
</IconLabel>
|
||||||
|
) : (
|
||||||
|
''
|
||||||
|
)}
|
||||||
|
</IconsGrid>
|
||||||
|
</FlexColumn>
|
||||||
|
</ChallengeStyle>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MiniChallenge;
|
@ -1,4 +1,4 @@
|
|||||||
import CHALLENGES_ACTION from '../model/ChallengesActionEnum';
|
import CHALLENGES_ACTION from '../model/ChallengesActions';
|
||||||
|
|
||||||
const challengeSearchQueryHandler = (event, challengesFromAPI, dispatch) => {
|
const challengeSearchQueryHandler = (event, challengesFromAPI, dispatch) => {
|
||||||
let searchQuery = event.target.value;
|
let searchQuery = event.target.value;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { ELEMENTS_PER_PAGE } from '../../../utils/globals';
|
import { ELEMENTS_PER_PAGE } from '../../../utils/globals';
|
||||||
import MiniChallenge from '../../../components/challenges_list/MiniChallenge';
|
import MiniChallenge from '../components/MiniChallenge';
|
||||||
import { Grid } from '../../../utils/containers';
|
import { Grid } from '../../../utils/containers';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { CHALLENGES_STATUS_FILTER } from '../../../utils/globals';
|
import { CHALLENGES_STATUS_FILTER } from '../../../utils/globals';
|
||||||
import CHALLENGES_ACTION from '../model/ChallengesActionEnum';
|
import CHALLENGES_ACTION from '../model/ChallengesActions';
|
||||||
|
|
||||||
const dateIsOlder = (newerDate, olderDate) => {
|
const dateIsOlder = (newerDate, olderDate) => {
|
||||||
if (newerDate.year > olderDate.year) return true;
|
if (newerDate.year > olderDate.year) return true;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import CHALLENGES_ACTION from './ChallengesActionEnum';
|
import CHALLENGES_ACTION from './ChallengesActions';
|
||||||
|
|
||||||
const ChallengesReducer = (state, action) => {
|
const ChallengesReducer = (state, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
@ -3,20 +3,20 @@ import { Container, FlexColumn, FlexRow, Svg } from '../../utils/containers';
|
|||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { H1, Medium } from '../../utils/fonts';
|
import { H1, Medium } from '../../utils/fonts';
|
||||||
import theme from '../../utils/theme';
|
import theme from '../../utils/theme';
|
||||||
import MobileChallengeMenu from './MobileChallengeMenu';
|
import MobileChallengeMenu from './components/MobileChallengeMenu';
|
||||||
import Leaderboard from './Leaderboard/Leaderboard';
|
import Leaderboard from '../Leaderboard/Leaderboard';
|
||||||
import Readme from './Readme';
|
import Readme from '../Readme';
|
||||||
import HowTo from './HowTo/HowTo';
|
import HowTo from '../HowTo/HowTo';
|
||||||
import MyEntries from './MyEntries/MyEntries';
|
import MyEntries from '../MyEntries/MyEntries';
|
||||||
import Submit from './Submit';
|
import Submit from '../Submit';
|
||||||
import Media from 'react-media';
|
import Media from 'react-media';
|
||||||
import DesktopChallengeMenu from './DesktopChallengeMenu';
|
import DesktopChallengeMenu from './components/DesktopChallengeMenu';
|
||||||
import { CHALLENGE_SECTIONS, RENDER_ICO } from '../../utils/globals';
|
import { CHALLENGE_SECTIONS, 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 '../generic/Loading';
|
import Loading from '../../components/generic/Loading';
|
||||||
import getUser from '../../api/getUser';
|
import getUser from '../../api/getUser';
|
||||||
import AllEntries from './AllEntries/AllEntries';
|
import AllEntries from '../AllEntries/AllEntries';
|
||||||
|
|
||||||
const Challenge = (props) => {
|
const Challenge = (props) => {
|
||||||
const challengeName = useParams().challengeId;
|
const challengeName = useParams().challengeId;
|
@ -1,15 +1,15 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { FlexColumn } from '../../utils/containers';
|
import { FlexColumn } from '../../../utils/containers';
|
||||||
import { H3 } from '../../utils/fonts';
|
import { H3 } from '../../../utils/fonts';
|
||||||
import PropsTypes from 'prop-types';
|
import PropsTypes from 'prop-types';
|
||||||
import KeyCloakService from '../../services/KeyCloakService';
|
import KeyCloakService from '../../../services/KeyCloakService';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
MENU_CHALLENGE_SECTIONS_WITH_LOGIN,
|
MENU_CHALLENGE_SECTIONS_WITH_LOGIN,
|
||||||
MENU_CHALLENGE_SECTIONS_NO_LOGIN,
|
MENU_CHALLENGE_SECTIONS_NO_LOGIN,
|
||||||
IS_MOBILE,
|
IS_MOBILE,
|
||||||
} from '../../utils/globals';
|
} from '../../../utils/globals';
|
||||||
|
|
||||||
const DesktopChallengeMenuStyle = styled(FlexColumn)`
|
const DesktopChallengeMenuStyle = styled(FlexColumn)`
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
@ -1,14 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FlexRow } from '../../utils/containers';
|
import { FlexRow } from '../../../utils/containers';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { Medium } from '../../utils/fonts';
|
import { Medium } from '../../../utils/fonts';
|
||||||
import PropsTypes from 'prop-types';
|
import PropsTypes from 'prop-types';
|
||||||
import KeyCloakService from '../../services/KeyCloakService';
|
import KeyCloakService from '../../../services/KeyCloakService';
|
||||||
import {
|
import {
|
||||||
CHALLENGE_SECTIONS,
|
CHALLENGE_SECTIONS,
|
||||||
MENU_CHALLENGE_SECTIONS_WITH_LOGIN,
|
MENU_CHALLENGE_SECTIONS_WITH_LOGIN,
|
||||||
MENU_CHALLENGE_SECTIONS_NO_LOGIN,
|
MENU_CHALLENGE_SECTIONS_NO_LOGIN,
|
||||||
} from '../../utils/globals';
|
} from '../../../utils/globals';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
const MenuOption = styled(Medium)`
|
const MenuOption = styled(Medium)`
|
1
src/pages/Challenge/index.js
Normal file
1
src/pages/Challenge/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from './Challenge';
|
@ -1,9 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import getFullUser from '../../../api/getFullUserInfo';
|
import getFullUser from '../../api/getFullUserInfo';
|
||||||
import KeyCloakService from '../../../services/KeyCloakService';
|
import KeyCloakService from '../../services/KeyCloakService';
|
||||||
import { FlexColumn } from '../../../utils/containers';
|
import { FlexColumn } from '../../utils/containers';
|
||||||
import { IS_MOBILE } from '../../../utils/globals';
|
import { IS_MOBILE } from '../../utils/globals';
|
||||||
import HowToContent from './sections/HowToContent';
|
import HowToContent from './components/HowToContent';
|
||||||
|
|
||||||
const HowTo = (props) => {
|
const HowTo = (props) => {
|
||||||
const [userFullInfo, setUserFullInfo] = React.useState(null);
|
const [userFullInfo, setUserFullInfo] = React.useState(null);
|
@ -1,9 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { IS_MOBILE } from '../../../../utils/globals';
|
import { IS_MOBILE } from '../../../utils/globals';
|
||||||
import { Body, H2, Medium } from '../../../../utils/fonts';
|
import { Body, H2, Medium } from '../../../utils/fonts';
|
||||||
import { FlexColumn, Grid } from '../../../../utils/containers';
|
import { FlexColumn, Grid } from '../../../utils/containers';
|
||||||
import CircleNumber from '../../../generic/CircleNumber';
|
import CircleNumber from '../../../components/generic/CircleNumber';
|
||||||
import CodeShell from '../../../generic/CodeShell';
|
import CodeShell from '../../../components/generic/CodeShell';
|
||||||
|
|
||||||
const HowToContent = (props) => {
|
const HowToContent = (props) => {
|
||||||
const pullCodeLineRender = () => {
|
const pullCodeLineRender = () => {
|
@ -1,20 +1,20 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Media from 'react-media';
|
import Media from 'react-media';
|
||||||
import theme from '../../../utils/theme';
|
import theme from '../../utils/theme';
|
||||||
import { FlexColumn } from '../../../utils/containers';
|
import { FlexColumn } from '../../utils/containers';
|
||||||
import { H2 } from '../../../utils/fonts';
|
import { H2 } from '../../utils/fonts';
|
||||||
import Table from '../Table';
|
import Table from '../../components/generic/Table';
|
||||||
import PropsTypes from 'prop-types';
|
import PropsTypes from 'prop-types';
|
||||||
import getChallengeLeaderboard from '../../../api/getChallengeLeaderboard';
|
import getChallengeLeaderboard from '../../api/getChallengeLeaderboard';
|
||||||
import leaderboardSearchQueryHandler from './leaderboardSearchQueryHandler';
|
import leaderboardSearchQueryHandler from './leaderboardSearchQueryHandler';
|
||||||
import {
|
import {
|
||||||
CALC_PAGES,
|
CALC_PAGES,
|
||||||
EVALUATIONS_FORMAT,
|
EVALUATIONS_FORMAT,
|
||||||
RENDER_WHEN,
|
RENDER_WHEN,
|
||||||
} from '../../../utils/globals';
|
} from '../../utils/globals';
|
||||||
import Search from '../../generic/Search';
|
import Search from '../../components/generic/Search';
|
||||||
import Pager from '../../generic/Pager';
|
import Pager from '../../components/generic/Pager';
|
||||||
import Loading from '../../generic/Loading';
|
import Loading from '../../components/generic/Loading';
|
||||||
|
|
||||||
const Leaderboard = (props) => {
|
const Leaderboard = (props) => {
|
||||||
const [entriesFromApi, setEntriesFromApi] = React.useState([]);
|
const [entriesFromApi, setEntriesFromApi] = React.useState([]);
|
@ -1,20 +1,20 @@
|
|||||||
import React from 'react';
|
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 Pager from '../../generic/Pager';
|
import Pager from '../../components/generic/Pager';
|
||||||
import {
|
import {
|
||||||
CALC_PAGES,
|
CALC_PAGES,
|
||||||
EVALUATIONS_FORMAT,
|
EVALUATIONS_FORMAT,
|
||||||
IS_MOBILE,
|
IS_MOBILE,
|
||||||
RENDER_WHEN,
|
RENDER_WHEN,
|
||||||
} from '../../../utils/globals';
|
} 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 '../../generic/Loading';
|
import Loading from '../../components/generic/Loading';
|
||||||
import Table from '../Table';
|
import Table from '../../components/generic/Table';
|
||||||
import myEntriesSearchQueryHandler from './myEntriesSearchQueryHandler';
|
import myEntriesSearchQueryHandler from './myEntriesSearchQueryHandler';
|
||||||
import Search from '../../generic/Search';
|
import Search from '../../components/generic/Search';
|
||||||
|
|
||||||
const MyEntries = (props) => {
|
const MyEntries = (props) => {
|
||||||
const [myEntriesFromAPI, setMyEntriesFromAPI] = React.useState({});
|
const [myEntriesFromAPI, setMyEntriesFromAPI] = React.useState({});
|
@ -1,14 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FlexColumn } from '../../utils/containers';
|
import { FlexColumn } from '../utils/containers';
|
||||||
import { Body, H2 } from '../../utils/fonts';
|
import { Body, H2 } from '../utils/fonts';
|
||||||
import Media from 'react-media';
|
import Media from 'react-media';
|
||||||
import theme from '../../utils/theme';
|
import theme from '../utils/theme';
|
||||||
import getChallengeFullDescription from '../../api/getChallengeFullDescription';
|
import getChallengeFullDescription from '../api/getChallengeFullDescription';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import InfoList from '../generic/InfoList';
|
import InfoList from '../components/generic/InfoList';
|
||||||
import Loading from '../generic/Loading';
|
import Loading from '../components/generic/Loading';
|
||||||
import PropsTypes from 'prop-types';
|
|
||||||
import MiniChallenge from '../challenges_list/MiniChallenge';
|
|
||||||
import { marked } from 'marked';
|
import { marked } from 'marked';
|
||||||
|
|
||||||
const ReadmeStyle = styled(Body)`
|
const ReadmeStyle = styled(Body)`
|
||||||
@ -154,14 +152,4 @@ const Readme = (props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
MiniChallenge.propTypes = {
|
|
||||||
challengeName: PropsTypes.string,
|
|
||||||
description: PropsTypes.string,
|
|
||||||
};
|
|
||||||
|
|
||||||
MiniChallenge.defaultProps = {
|
|
||||||
challengeName: '',
|
|
||||||
description: '',
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Readme;
|
export default Readme;
|
@ -2,40 +2,58 @@ import React from 'react';
|
|||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import { FlexColumn } from '../../utils/containers';
|
import { FlexColumn } from '../../utils/containers';
|
||||||
import { H2, Menu } from '../../utils/fonts';
|
import { H2, Menu } from '../../utils/fonts';
|
||||||
import SubmitInput from '../generic/SubmitInput';
|
import SubmitInput from '../../components/generic/SubmitInput';
|
||||||
import Button from '../generic/Button';
|
import Button from '../../components/generic/Button';
|
||||||
import theme from '../../utils/theme';
|
import theme from '../../utils/theme';
|
||||||
import challengeSubmission from '../../api/challengeSubmissionPost';
|
import challengeSubmission from '../../api/challengeSubmissionPost';
|
||||||
import Loading from '../generic/Loading';
|
import Loading from '../../components/generic/Loading';
|
||||||
import getTags from '../../api/getTags';
|
import getTags from '../../api/getTags';
|
||||||
import DropdownWithPopup from '../generic/DropdownWithPopup';
|
import TagsChoose from './components/TagsChoose';
|
||||||
|
import SubmitReducer from './model/SubmitReducer';
|
||||||
|
import SUBMIT_ACTION from './model/SubmitActionEnum';
|
||||||
|
|
||||||
const Submit = (props) => {
|
const Submit = (props) => {
|
||||||
const [description, setDescription] = React.useState('');
|
const [state, dispatch] = React.useReducer(SubmitReducer, {
|
||||||
const [repoUrl, setRepoUrl] = React.useState('');
|
description: '',
|
||||||
const [repoBranch, setRepoBranch] = React.useState('');
|
repoUrl: '',
|
||||||
const [loading, setLoading] = React.useState(false);
|
repoBranch: '',
|
||||||
const [tags, setTags] = React.useState([]);
|
submissionLoading: false,
|
||||||
// eslint-disable-next-line no-unused-vars
|
tags: [],
|
||||||
const [submissionTags, setSubmissionTags] = React.useState([]);
|
submissionTags: [],
|
||||||
|
});
|
||||||
|
|
||||||
React.useMemo(() => {
|
React.useMemo(() => {
|
||||||
getTags(setTags);
|
getTags(dispatch);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const challengeSubmissionSubmit = () => {
|
const challengeSubmissionSubmit = () => {
|
||||||
setLoading(true);
|
dispatch({ type: SUBMIT_ACTION.TOGGLE_SUBMISSION_LOADING });
|
||||||
challengeSubmission(
|
challengeSubmission(
|
||||||
props.challengeName,
|
props.challengeName,
|
||||||
repoUrl,
|
state.repoUrl,
|
||||||
repoBranch,
|
state.repoBranch,
|
||||||
description,
|
state.description,
|
||||||
setLoading
|
dispatch
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!loading) {
|
const setDescription = (value) => {
|
||||||
console.log(tags);
|
dispatch({ type: SUBMIT_ACTION.SET_DESCRIPTION, payload: value });
|
||||||
|
};
|
||||||
|
|
||||||
|
const setRepoUrl = (value) => {
|
||||||
|
dispatch({ type: SUBMIT_ACTION.SET_REPO_URL, payload: value });
|
||||||
|
};
|
||||||
|
|
||||||
|
const setRepoBranch = (value) => {
|
||||||
|
dispatch({ type: SUBMIT_ACTION.SET_REPO_BRANCH, payload: value });
|
||||||
|
};
|
||||||
|
|
||||||
|
const addSubmissionTag = React.useCallback((value) => {
|
||||||
|
dispatch({ type: SUBMIT_ACTION.ADD_SUBMISSION_TAG, payload: value });
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!state.submissionLoading) {
|
||||||
return (
|
return (
|
||||||
<FlexColumn
|
<FlexColumn
|
||||||
margin="40px 0 0 0"
|
margin="40px 0 0 0"
|
||||||
@ -56,9 +74,11 @@ const Submit = (props) => {
|
|||||||
/>
|
/>
|
||||||
<SubmitInput label="Submission repo URL" handler={setRepoUrl} />
|
<SubmitInput label="Submission repo URL" handler={setRepoUrl} />
|
||||||
<SubmitInput label="Submission repo branch" handler={setRepoBranch} />
|
<SubmitInput label="Submission repo branch" handler={setRepoBranch} />
|
||||||
<DropdownWithPopup
|
<TagsChoose
|
||||||
label="Submission tags"
|
label="Submission tags"
|
||||||
handler={setSubmissionTags}
|
addSubmissionTag={addSubmissionTag}
|
||||||
|
tags={state.tags}
|
||||||
|
submissionTags={state.submissionTags}
|
||||||
/>
|
/>
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
<Button width="122px" height="44px" handler={challengeSubmissionSubmit}>
|
<Button width="122px" height="44px" handler={challengeSubmissionSubmit}>
|
43
src/pages/Submit/components/TagsChoose/TagsChoose.js
Normal file
43
src/pages/Submit/components/TagsChoose/TagsChoose.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { FlexRow, Grid } from '../../../../utils/containers';
|
||||||
|
import { Medium } from '../../../../utils/fonts';
|
||||||
|
import ImageButton from '../../../../components/generic/ImageButton';
|
||||||
|
import pencilIco from '../../../../assets/pencil_ico.svg';
|
||||||
|
import TagsChoosePopUp from '../TagsChoosePopup/TagsChoosePopUp';
|
||||||
|
import { createPortal } from 'react-dom';
|
||||||
|
import TagsChooseStyle from './TagsChooseStyle';
|
||||||
|
|
||||||
|
const TagsChoose = (props) => {
|
||||||
|
const [tagsPopUp, setTagsPopUp] = React.useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TagsChooseStyle
|
||||||
|
onClick={() => {
|
||||||
|
if (!tagsPopUp) setTagsPopUp(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Medium as="label" htmlFor={props.label}>
|
||||||
|
{props.label}
|
||||||
|
</Medium>
|
||||||
|
<Grid
|
||||||
|
className="TagsChooseStyle__grid"
|
||||||
|
onChange={(e) => props.handler(e.target.value)}
|
||||||
|
>
|
||||||
|
<FlexRow className="TagsChooseStyle__tags-container">tags</FlexRow>
|
||||||
|
<ImageButton src={pencilIco} width="20px" height="20px" />
|
||||||
|
</Grid>
|
||||||
|
{tagsPopUp &&
|
||||||
|
createPortal(
|
||||||
|
<TagsChoosePopUp
|
||||||
|
tags={props.tags}
|
||||||
|
submissionTags={props.submissionTags}
|
||||||
|
addSubmissionTag={props.addSubmissionTag}
|
||||||
|
setTagsPopUp={setTagsPopUp}
|
||||||
|
/>,
|
||||||
|
document.body
|
||||||
|
)}
|
||||||
|
</TagsChooseStyle>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TagsChoose;
|
30
src/pages/Submit/components/TagsChoose/TagsChooseStyle.js
Normal file
30
src/pages/Submit/components/TagsChoose/TagsChooseStyle.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
import { FlexColumn } from '../../../../utils/containers';
|
||||||
|
|
||||||
|
const TagsChooseStyle = styled(FlexColumn)`
|
||||||
|
cursor: pointer;
|
||||||
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
|
align-items: flex-start;
|
||||||
|
* {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.TagsChooseStyle__grid {
|
||||||
|
border-radius: 4px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100px;
|
||||||
|
border: 1px solid ${({ theme }) => theme.colors.dark};
|
||||||
|
box-shadow: 1px 2px 4px rgba(52, 52, 52, 0.25);
|
||||||
|
padding: 12px;
|
||||||
|
grid-template-columns: 1fr auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.TagsChooseStyle__tags-container {
|
||||||
|
height: 100%;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default TagsChooseStyle;
|
1
src/pages/Submit/components/TagsChoose/index.js
Normal file
1
src/pages/Submit/components/TagsChoose/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from './TagsChoose';
|
@ -0,0 +1,64 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PopUp from '../../../../components/generic/PopUp';
|
||||||
|
import { FlexColumn, FlexRow } from '../../../../utils/containers';
|
||||||
|
import Search from '../../../../components/generic/Search';
|
||||||
|
import theme from '../../../../utils/theme';
|
||||||
|
import Button from '../../../../components/generic/Button';
|
||||||
|
import TagsChoosePopUpStyle from './TagsChoosePopUpStyle';
|
||||||
|
import tagColorHandle from './functions/tagColorHandle';
|
||||||
|
|
||||||
|
const TagsChoosePopUp = (props) => {
|
||||||
|
return (
|
||||||
|
<PopUp
|
||||||
|
width="50%"
|
||||||
|
height="80vh"
|
||||||
|
padding="36px 32px 0"
|
||||||
|
closeHandler={() => props.setTagsPopUp(false)}
|
||||||
|
>
|
||||||
|
<TagsChoosePopUpStyle>
|
||||||
|
<Search />
|
||||||
|
<FlexColumn as="list" className="TagsChoosePopUpStyle__tags-list">
|
||||||
|
{props.tags.map((tag, index) => {
|
||||||
|
return (
|
||||||
|
<FlexRow
|
||||||
|
key={`tag-${index}`}
|
||||||
|
onClick={() => props.addSubmissionTag(tag.name)}
|
||||||
|
className="TagsChoosePopUpStyle__tag-item"
|
||||||
|
backgroundColor={tagColorHandle(
|
||||||
|
theme,
|
||||||
|
index,
|
||||||
|
tag,
|
||||||
|
props.submissionTags
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{tag.name}
|
||||||
|
</FlexRow>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</FlexColumn>
|
||||||
|
<FlexRow width="100%" gap="20px" alignmentX="flex-start">
|
||||||
|
<Button height="32px" width="76px">
|
||||||
|
Done
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
height="32px"
|
||||||
|
width="76px"
|
||||||
|
backgroundColor={theme.colors.dark08}
|
||||||
|
>
|
||||||
|
Clear
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
height="32px"
|
||||||
|
width="76px"
|
||||||
|
backgroundColor={theme.colors.dark}
|
||||||
|
margin="0 0 0 auto"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</FlexRow>
|
||||||
|
</TagsChoosePopUpStyle>
|
||||||
|
</PopUp>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TagsChoosePopUp;
|
@ -0,0 +1,31 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
import { FlexColumn } from '../../../../utils/containers';
|
||||||
|
|
||||||
|
const TagsChoosePopUpStyle = styled(FlexColumn)`
|
||||||
|
width: 100%;
|
||||||
|
justify-content: flex-start;
|
||||||
|
height: 100%;
|
||||||
|
gap: 24px;
|
||||||
|
|
||||||
|
.TagsChoosePopUpStyle__tags-list {
|
||||||
|
height: 80%;
|
||||||
|
width: 100%;
|
||||||
|
overflow-y: scroll;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.TagsChoosePopUpStyle__tag-item {
|
||||||
|
height: 42px;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: flex-start;
|
||||||
|
padding: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease-in-out;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: ${({ theme }) => theme.colors.green03};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default TagsChoosePopUpStyle;
|
@ -0,0 +1,7 @@
|
|||||||
|
const tagColorHandle = (theme, index, tag, tags) => {
|
||||||
|
if (tags.includes(tag.name)) return theme.colors.green;
|
||||||
|
if (index % 2 === 0) return theme.colors.dark01;
|
||||||
|
return theme.colors.white;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default tagColorHandle;
|
1
src/pages/Submit/components/TagsChoosePopup/index.js
Normal file
1
src/pages/Submit/components/TagsChoosePopup/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from './TagsChoosePopUp';
|
1
src/pages/Submit/index.js
Normal file
1
src/pages/Submit/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from './Submit';
|
12
src/pages/Submit/model/SubmitActionEnum.js
Normal file
12
src/pages/Submit/model/SubmitActionEnum.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
const SUBMIT_ACTION = {
|
||||||
|
SET_DESCRIPTION: 'set_description',
|
||||||
|
SET_REPO_URL: 'set_repo_url',
|
||||||
|
SET_REPO_BRANCH: 'set_repo_branch',
|
||||||
|
TOGGLE_SUBMISSION_LOADING: 'toggle_submission_loading',
|
||||||
|
LOAD_TAGS: 'load_tags',
|
||||||
|
ADD_SUBMISSION_TAGS: 'add_submission_tag',
|
||||||
|
REMOVE_SUBMISSION_TAGS: 'remove_submission_tag',
|
||||||
|
CLEAR_SUBMISSION_TAGS: 'clear_submission_tags',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SUBMIT_ACTION;
|
30
src/pages/Submit/model/SubmitReducer.js
Normal file
30
src/pages/Submit/model/SubmitReducer.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import SUBMIT_ACTION from './SubmitActionEnum';
|
||||||
|
|
||||||
|
const SubmitReducer = (state, action) => {
|
||||||
|
console.log('SubmitReducer');
|
||||||
|
let initTags = state.tags;
|
||||||
|
let newSubmissionTags = state.submissionTags;
|
||||||
|
switch (action.type) {
|
||||||
|
case SUBMIT_ACTION.SET_DESCRIPTION:
|
||||||
|
return { ...state, description: action.payload };
|
||||||
|
case SUBMIT_ACTION.SET_REPO_BRANCH:
|
||||||
|
return { ...state, repoBranch: action.payload };
|
||||||
|
case SUBMIT_ACTION.SET_REPO_URL:
|
||||||
|
return { ...state, repoUrl: action.payload };
|
||||||
|
case SUBMIT_ACTION.TOGGLE_SUBMISSION_LOADING:
|
||||||
|
return { ...state, submissionLoading: !state.submissionLoading };
|
||||||
|
case SUBMIT_ACTION.LOAD_TAGS:
|
||||||
|
if (state.tags.length === 0) initTags = action.payload;
|
||||||
|
return { ...state, tags: initTags };
|
||||||
|
case SUBMIT_ACTION.ADD_SUBMISSION_TAG:
|
||||||
|
if (!newSubmissionTags.includes(action.payload))
|
||||||
|
newSubmissionTags.push(action.payload);
|
||||||
|
return { ...state, submissionTags: newSubmissionTags };
|
||||||
|
case SUBMIT_ACTION.CLEAR_SUBMISSION_TAGS:
|
||||||
|
return { ...state, submissionTags: [] };
|
||||||
|
default:
|
||||||
|
throw new Error('Undefined action in SubmitReducer!');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SubmitReducer;
|
@ -1,6 +1,7 @@
|
|||||||
const colors = {
|
const colors = {
|
||||||
white: '#FCFCFC',
|
white: '#FCFCFC',
|
||||||
green: '#1B998B',
|
green: '#1B998B',
|
||||||
|
blue: '#4B8FF0',
|
||||||
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',
|
||||||
|
@ -37,6 +37,7 @@ const Container = styled.div`
|
|||||||
list-style: ${({ listStyle }) => (listStyle ? listStyle : 'none')};
|
list-style: ${({ listStyle }) => (listStyle ? listStyle : 'none')};
|
||||||
overflow-wrap: ${({ overflowWrap }) =>
|
overflow-wrap: ${({ overflowWrap }) =>
|
||||||
overflowWrap ? overflowWrap : 'normal'};
|
overflowWrap ? overflowWrap : 'normal'};
|
||||||
|
overflow-y: ${({ overflowY }) => (overflowY ? overflowY : 'none')};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const FlexRow = styled(Container)`
|
const FlexRow = styled(Container)`
|
||||||
|
Loading…
Reference in New Issue
Block a user