get current user profile info to disable edit and delete submission
This commit is contained in:
parent
4dbcc540d6
commit
970a948cec
@ -7,6 +7,24 @@ import deleteIco from '../../../../../assets/delete_ico.svg';
|
|||||||
import KeyCloakService from '../../../../../services/KeyCloakService';
|
import KeyCloakService from '../../../../../services/KeyCloakService';
|
||||||
|
|
||||||
const TableRowFooter = ({ rowFooter, item, i, deleteItem, editItem }) => {
|
const TableRowFooter = ({ rowFooter, item, i, deleteItem, editItem }) => {
|
||||||
|
const [profileInfo, setProfileInfo] = React.useState(null);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
KeyCloakService.getProfileInfo(setProfileInfo);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const isActive = () => {
|
||||||
|
if (!KeyCloakService.isLoggedIn()) return false;
|
||||||
|
if (profileInfo) {
|
||||||
|
if (
|
||||||
|
profileInfo?.preferred_username !== item.submitter &&
|
||||||
|
profileInfo?.name !== item.submitter
|
||||||
|
)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
if (rowFooter) {
|
if (rowFooter) {
|
||||||
return (
|
return (
|
||||||
<FlexRow className="TableStyle__row-footer">
|
<FlexRow className="TableStyle__row-footer">
|
||||||
@ -16,7 +34,7 @@ const TableRowFooter = ({ rowFooter, item, i, deleteItem, editItem }) => {
|
|||||||
{ icon: pensilIco, handler: () => editItem() },
|
{ icon: pensilIco, handler: () => editItem() },
|
||||||
{ icon: deleteIco, handler: () => deleteItem() },
|
{ icon: deleteIco, handler: () => deleteItem() },
|
||||||
]}
|
]}
|
||||||
active={KeyCloakService.isLoggedIn()}
|
active={isActive()}
|
||||||
i={i}
|
i={i}
|
||||||
/>
|
/>
|
||||||
</FlexRow>
|
</FlexRow>
|
||||||
|
@ -4,10 +4,10 @@ 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 './components/MobileChallengeMenu';
|
import MobileChallengeMenu from './components/MobileChallengeMenu';
|
||||||
import Leaderboard from '../Leaderboard/Leaderboard';
|
import Leaderboard from '../Leaderboard';
|
||||||
import Readme from '../Readme';
|
import Readme from '../Readme';
|
||||||
import HowTo from '../HowTo/HowTo';
|
import HowTo from '../HowTo';
|
||||||
import MyEntries from '../MyEntries/MyEntries';
|
import MyEntries from '../MyEntries';
|
||||||
import Submit from '../Submit';
|
import Submit from '../Submit';
|
||||||
import Media from 'react-media';
|
import Media from 'react-media';
|
||||||
import DesktopChallengeMenu from './components/DesktopChallengeMenu';
|
import DesktopChallengeMenu from './components/DesktopChallengeMenu';
|
||||||
@ -15,7 +15,7 @@ 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 '../../components/generic/Loading';
|
import Loading from '../../components/generic/Loading';
|
||||||
import AllEntries from '../AllEntries/AllEntries';
|
import AllEntries from '../AllEntries';
|
||||||
|
|
||||||
const Challenge = (props) => {
|
const Challenge = (props) => {
|
||||||
const challengeName = useParams().challengeId;
|
const challengeName = useParams().challengeId;
|
||||||
@ -37,7 +37,11 @@ const Challenge = (props) => {
|
|||||||
);
|
);
|
||||||
case CHALLENGE_SECTIONS.ALL_ENTRIES:
|
case CHALLENGE_SECTIONS.ALL_ENTRIES:
|
||||||
return (
|
return (
|
||||||
<AllEntries challengeName={challengeName} setLoading={setLoading} popUpMessageHandler={props.popUpMessageHandler} />
|
<AllEntries
|
||||||
|
challengeName={challengeName}
|
||||||
|
setLoading={setLoading}
|
||||||
|
popUpMessageHandler={props.popUpMessageHandler}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
case CHALLENGE_SECTIONS.README:
|
case CHALLENGE_SECTIONS.README:
|
||||||
return (
|
return (
|
||||||
@ -56,7 +60,12 @@ const Challenge = (props) => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case CHALLENGE_SECTIONS.MY_ENTRIES:
|
case CHALLENGE_SECTIONS.MY_ENTRIES:
|
||||||
return <MyEntries challengeName={challengeName} popUpMessageHandler={props.popUpMessageHandler} />;
|
return (
|
||||||
|
<MyEntries
|
||||||
|
challengeName={challengeName}
|
||||||
|
popUpMessageHandler={props.popUpMessageHandler}
|
||||||
|
/>
|
||||||
|
);
|
||||||
case CHALLENGE_SECTIONS.SUBMIT:
|
case CHALLENGE_SECTIONS.SUBMIT:
|
||||||
return <Submit challengeName={challengeName} setLoading={setLoading} />;
|
return <Submit challengeName={challengeName} setLoading={setLoading} />;
|
||||||
default:
|
default:
|
||||||
|
@ -1,65 +1,13 @@
|
|||||||
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 { 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 InfoList from '../../components/generic/InfoList';
|
||||||
import InfoList from '../components/generic/InfoList';
|
import Loading from '../../components/generic/Loading';
|
||||||
import Loading from '../components/generic/Loading';
|
|
||||||
import { marked } from 'marked';
|
import { marked } from 'marked';
|
||||||
|
import ReadmeStyle from './ReadmeStyle';
|
||||||
const ReadmeStyle = styled(Body)`
|
|
||||||
* {
|
|
||||||
font-weight: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
font-family: 'Kanit', sans-serif;
|
|
||||||
margin: 32px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
font-family: 'Kanit', sans-serif;
|
|
||||||
font-weight: inherit;
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 22px;
|
|
||||||
margin: 24px 0;
|
|
||||||
|
|
||||||
@media (min-width: ${({ theme }) => theme.overMobile}) {
|
|
||||||
font-size: 22px;
|
|
||||||
line-height: 26px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 20px;
|
|
||||||
|
|
||||||
@media (min-width: ${({ theme }) => theme.overMobile}) {
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 22px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
font-weight: 400;
|
|
||||||
font-size: 14px;
|
|
||||||
line-height: 20px;
|
|
||||||
color: ${({ theme }) => theme.colors.dark};
|
|
||||||
text-decoration: none;
|
|
||||||
|
|
||||||
@media (min-width: ${({ theme }) => theme.overMobile}) {
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 22px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Readme = (props) => {
|
const Readme = (props) => {
|
||||||
const [fullDescription, setFullDescription] = React.useState('');
|
const [fullDescription, setFullDescription] = React.useState('');
|
||||||
@ -117,8 +65,13 @@ const Readme = (props) => {
|
|||||||
|
|
||||||
const desktopRender = () => {
|
const desktopRender = () => {
|
||||||
return (
|
return (
|
||||||
<FlexColumn as="section" padding="20px" gap="64px">
|
<FlexColumn
|
||||||
<FlexColumn gap="32px">
|
as="section"
|
||||||
|
className="Readme__section"
|
||||||
|
padding="20px"
|
||||||
|
gap="64px"
|
||||||
|
>
|
||||||
|
<FlexColumn className="Readme__info" gap="32px">
|
||||||
<H2 as="h2">Info</H2>
|
<H2 as="h2">Info</H2>
|
||||||
<InfoList
|
<InfoList
|
||||||
iconsSize="32px"
|
iconsSize="32px"
|
||||||
@ -126,7 +79,12 @@ const Readme = (props) => {
|
|||||||
deadline={props.deadline}
|
deadline={props.deadline}
|
||||||
/>
|
/>
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
<FlexColumn alignmentX="flex-start" width="80%" maxWidth="1200px">
|
<FlexColumn
|
||||||
|
className="Readme__container"
|
||||||
|
alignmentX="flex-start"
|
||||||
|
width="80%"
|
||||||
|
maxWidth="1200px"
|
||||||
|
>
|
||||||
<ReadmeStyle
|
<ReadmeStyle
|
||||||
as={fullDescription ? 'section' : 'p'}
|
as={fullDescription ? 'section' : 'p'}
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
64
src/pages/Readme/ReadmeStyle.js
Normal file
64
src/pages/Readme/ReadmeStyle.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const ReadmeStyle = styled.section`
|
||||||
|
padding: 20px;
|
||||||
|
gap: 24px;
|
||||||
|
|
||||||
|
@media (min-width: ${({ theme }) => theme.overMobile}) {
|
||||||
|
gap: 64px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .ReadmeStyle__content { */
|
||||||
|
* {
|
||||||
|
font-weight: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-family: 'Kanit', sans-serif;
|
||||||
|
margin: 32px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
font-family: 'Kanit', sans-serif;
|
||||||
|
font-weight: inherit;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 22px;
|
||||||
|
margin: 24px 0;
|
||||||
|
|
||||||
|
@media (min-width: ${({ theme }) => theme.overMobile}) {
|
||||||
|
font-size: 22px;
|
||||||
|
line-height: 26px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
|
||||||
|
@media (min-width: ${({ theme }) => theme.overMobile}) {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: ${({ theme }) => theme.colors.dark};
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
@media (min-width: ${({ theme }) => theme.overMobile}) {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* } */
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default ReadmeStyle;
|
32
src/pages/Readme/components/ReadmeDesktop.js
Normal file
32
src/pages/Readme/components/ReadmeDesktop.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { FlexColumn } from '../../../utils/containers';
|
||||||
|
import { H2 } from '../../../utils/fonts';
|
||||||
|
import InfoList from '../../../components/generic/InfoList';
|
||||||
|
import ReadmeStyle from '../ReadmeStyle';
|
||||||
|
|
||||||
|
const ReadmeDesktop = (props) => {
|
||||||
|
return (
|
||||||
|
<FlexColumn as="section" padding="20px" gap="64px">
|
||||||
|
<FlexColumn gap="32px">
|
||||||
|
<H2 as="h2">Info</H2>
|
||||||
|
<InfoList
|
||||||
|
iconsSize="32px"
|
||||||
|
metric={props.metric}
|
||||||
|
deadline={props.deadline}
|
||||||
|
/>
|
||||||
|
</FlexColumn>
|
||||||
|
<FlexColumn alignmentX="flex-start" width="80%" maxWidth="1200px">
|
||||||
|
<ReadmeStyle
|
||||||
|
as={props.fullDescription ? 'section' : 'p'}
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: props.fullDescription
|
||||||
|
? props.parseMarkdownResponse(props.fullDescription)
|
||||||
|
: props.description,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</FlexColumn>
|
||||||
|
</FlexColumn>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ReadmeDesktop;
|
32
src/pages/Readme/components/ReadmeMobile.js
Normal file
32
src/pages/Readme/components/ReadmeMobile.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { FlexColumn } from '../../../utils/containers';
|
||||||
|
import { H2 } from '../../../utils/fonts';
|
||||||
|
import InfoList from '../../../components/generic/InfoList';
|
||||||
|
import ReadmeStyle from '../ReadmeStyle';
|
||||||
|
|
||||||
|
const ReadmeMobile = (props) => {
|
||||||
|
return (
|
||||||
|
<FlexColumn as="section" padding="20px" gap="24px">
|
||||||
|
<FlexColumn gap="12px" alignmentX="flex-start">
|
||||||
|
<H2 as="h2">Info</H2>
|
||||||
|
<InfoList
|
||||||
|
iconsSize="24px"
|
||||||
|
metric={props.metric}
|
||||||
|
deadline={props.deadline}
|
||||||
|
/>
|
||||||
|
</FlexColumn>
|
||||||
|
<FlexColumn alignmentX="flex-start" maxWidth="260px">
|
||||||
|
<ReadmeStyle
|
||||||
|
as={props.fullDescription ? 'article' : 'p'}
|
||||||
|
dangerouslySetInnerHTML={{
|
||||||
|
__html: props.fullDescription
|
||||||
|
? props.parseMarkdownResponse(props.fullDescription)
|
||||||
|
: props.description,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</FlexColumn>
|
||||||
|
</FlexColumn>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ReadmeMobile;
|
1
src/pages/Readme/index.js
Normal file
1
src/pages/Readme/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default } from './Readme';
|
@ -1,5 +1,6 @@
|
|||||||
import Keycloak from 'keycloak-js';
|
import Keycloak from 'keycloak-js';
|
||||||
import { POLICY_PRIVACY_PAGE, ROOT_URL } from '../utils/globals';
|
import { POLICY_PRIVACY_PAGE, ROOT_URL } from '../utils/globals';
|
||||||
|
import SESSION_STORAGE from '../utils/sessionStorage';
|
||||||
|
|
||||||
const _kc = new Keycloak({
|
const _kc = new Keycloak({
|
||||||
url: process.env.REACT_APP_KC_URL,
|
url: process.env.REACT_APP_KC_URL,
|
||||||
@ -30,14 +31,17 @@ const doLogin = () => {
|
|||||||
if (privacyPolicyAccept !== 'accept') {
|
if (privacyPolicyAccept !== 'accept') {
|
||||||
window.location.replace(`${ROOT_URL}${POLICY_PRIVACY_PAGE}/login`);
|
window.location.replace(`${ROOT_URL}${POLICY_PRIVACY_PAGE}/login`);
|
||||||
} else {
|
} else {
|
||||||
sessionStorage.setItem('logout', '');
|
sessionStorage.setItem(SESSION_STORAGE.LOGOUT, '');
|
||||||
_kc.login();
|
_kc.login();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const doLogout = () => {
|
const doLogout = () => {
|
||||||
sessionStorage.clear();
|
sessionStorage.clear();
|
||||||
sessionStorage.setItem('logout', 'yes');
|
sessionStorage.setItem(
|
||||||
|
SESSION_STORAGE.LOGOUT,
|
||||||
|
SESSION_STORAGE.STATIC_VALUE.YES
|
||||||
|
);
|
||||||
_kc.logout();
|
_kc.logout();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,10 +66,13 @@ const getUsername = () => _kc.tokenParsed?.preferred_username;
|
|||||||
const hasRole = (roles) => roles.some((role) => _kc.hasRealmRole(role));
|
const hasRole = (roles) => roles.some((role) => _kc.hasRealmRole(role));
|
||||||
|
|
||||||
const goToProfile = () => {
|
const goToProfile = () => {
|
||||||
console.log(_kc.loadUserProfile());
|
|
||||||
_kc.accountManagement();
|
_kc.accountManagement();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getProfileInfo = async (setProfileInfo) => {
|
||||||
|
_kc.loadUserInfo().then((response) => setProfileInfo(response));
|
||||||
|
};
|
||||||
|
|
||||||
const KeyCloakService = {
|
const KeyCloakService = {
|
||||||
initKeycloak,
|
initKeycloak,
|
||||||
doLogin,
|
doLogin,
|
||||||
@ -77,6 +84,7 @@ const KeyCloakService = {
|
|||||||
hasRole,
|
hasRole,
|
||||||
doRegister,
|
doRegister,
|
||||||
goToProfile,
|
goToProfile,
|
||||||
|
getProfileInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default KeyCloakService;
|
export default KeyCloakService;
|
||||||
|
Loading…
Reference in New Issue
Block a user