get current user profile info to disable edit and delete submission

This commit is contained in:
Mateusz Tylka 2023-09-29 16:07:36 +02:00
parent 4dbcc540d6
commit 970a948cec
8 changed files with 194 additions and 72 deletions

View File

@ -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>

View File

@ -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:

View File

@ -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={{

View 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;

View 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;

View 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;

View File

@ -0,0 +1 @@
export { default } from './Readme';

View File

@ -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;