Merge branch 'master' of git.plannaplan.pl:y0rune/frontend into unit-tests

This commit is contained in:
wrzesinski-hubert 2021-01-14 14:29:14 +01:00
commit 78e63ce587
4 changed files with 36 additions and 13 deletions

View File

@ -1,4 +1,4 @@
import React, { ElementType, useContext, useState } from 'react'; import React, { ElementType, useContext, useEffect, useState } from 'react';
import Topbar from './Topbar'; import Topbar from './Topbar';
import { Transfer } from './Transfer'; import { Transfer } from './Transfer';
import { Admin } from './Admin'; import { Admin } from './Admin';
@ -8,6 +8,7 @@ import styled from 'styled-components';
import { coursesContext } from '../contexts/CoursesProvider'; import { coursesContext } from '../contexts/CoursesProvider';
import LoadingOverlay from 'react-loading-overlay'; import LoadingOverlay from 'react-loading-overlay';
import { SyncLoader } from 'react-spinners'; import { SyncLoader } from 'react-spinners';
import { CASContext } from '../contexts/CASProvider';
const Wrapper = styled.div` const Wrapper = styled.div`
display: flex; display: flex;
height: calc(100vh - 80px); height: calc(100vh - 80px);
@ -19,17 +20,21 @@ const Wrapper = styled.div`
export const App = () => { export const App = () => {
const { isDataLoading } = useContext(coursesContext)!; const { isDataLoading } = useContext(coursesContext)!;
const { isFetchingToken, user, role } = useContext(CASContext)!;
const [isOpenTransfer, setOpenTransfer] = useState(false); const [isOpenTransfer, setOpenTransfer] = useState(false);
const handleTransfer = () => { const handleTransfer = () => {
setOpenTransfer(!isOpenTransfer); setOpenTransfer(!isOpenTransfer);
}; };
const userPrivilige = localStorage.getItem('userPrivilige'); const userPrivilige = localStorage.getItem('userPrivilige');
console.log('role of that user is: ', role);
useEffect(() => {
console.log('is fetching token: ', isFetchingToken);
}, [isFetchingToken]);
return ( return (
<> <>
<LoadingOverlay active={isDataLoading} spinner={<SyncLoader />}> <LoadingOverlay active={role === undefined} spinner={<SyncLoader />}>
<Topbar handleTransfer={handleTransfer} /> <Topbar handleTransfer={handleTransfer} />
<Transfer isOpen={isOpenTransfer} handleClose={handleTransfer} /> <Transfer isOpen={isOpenTransfer} handleClose={handleTransfer} />
<Wrapper> <Wrapper>
@ -38,9 +43,8 @@ export const App = () => {
<Scheduler /> <Scheduler />
<Rightbar /> <Rightbar />
</> </>
)} { userPrivilige === 'DEANERY' && ( )}{' '}
<Admin /> {userPrivilige === 'DEANERY' && <Admin />}
)}
</Wrapper> </Wrapper>
</LoadingOverlay> </LoadingOverlay>
</> </>

View File

@ -1,4 +1,4 @@
import React, { useState, MouseEvent, ChangeEvent, useEffect, useCallback, useContext } from 'react'; import React, { useState, MouseEvent, ChangeEvent, useEffect, useCallback, useContext, useRef } from 'react';
import { ReactComponent as Close } from '../assets/close.svg'; import { ReactComponent as Close } from '../assets/close.svg';
import ProfileIcon from '../assets/account.svg'; import ProfileIcon from '../assets/account.svg';
import { Profile } from './Profile'; import { Profile } from './Profile';
@ -7,6 +7,8 @@ import styled from 'styled-components/macro';
import ClickAwayListener from 'react-click-away-listener'; import ClickAwayListener from 'react-click-away-listener';
import { SelectMenu } from './SelectMenu'; import { SelectMenu } from './SelectMenu';
import { studentsContext } from '../contexts/StudentsProvider'; import { studentsContext } from '../contexts/StudentsProvider';
import { CASContext } from '../contexts/CASProvider';
import { render } from 'react-dom';
const Topbar = styled.div` const Topbar = styled.div`
background-color: #e3e5ed; background-color: #e3e5ed;
@ -135,14 +137,18 @@ interface TopbarProps {
} }
export default function ({ handleTransfer }: TopbarProps) { export default function ({ handleTransfer }: TopbarProps) {
const userPrivilige = localStorage.getItem('userPrivilige');
const { selectedStudent } = useContext(studentsContext)!; const { selectedStudent } = useContext(studentsContext)!;
const { role } = useContext(CASContext)!;
const [clearInput, setClearInput] = useState(false); const [clearInput, setClearInput] = useState(false);
const [isPolish, setIsPolish] = useState(false); const [isPolish, setIsPolish] = useState(false);
const [anchorEl, setAnchorEl] = useState<HTMLImageElement | null>(null); const [anchorEl, setAnchorEl] = useState<HTMLImageElement | null>(null);
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [input, setInput] = useState(''); const [input, setInput] = useState('');
const [selectedOption, setSelectedOption] = useState('przedmioty'); const [selectedOption, setSelectedOption] = useState(role === 'STUDENT' ? 'przedmioty' : 'studenci');
useEffect(() => {
role && setSelectedOption(role === 'STUDENT' ? 'przedmioty' : 'studenci');
}, [role]);
const changeSelectedOption = (option: string) => setSelectedOption(option); const changeSelectedOption = (option: string) => setSelectedOption(option);
@ -176,14 +182,14 @@ export default function ({ handleTransfer }: TopbarProps) {
<FlexboxColumn> <FlexboxColumn>
<ClickAwayListener onClickAway={handleCloseDropdown}> <ClickAwayListener onClickAway={handleCloseDropdown}>
<Flexbox> <Flexbox>
{userPrivilige !== 'STUDENT' && ( {role !== 'STUDENT' && (
<SelectMenu <SelectMenu
changeSelectedOption={changeSelectedOption} changeSelectedOption={changeSelectedOption}
selectedOption={selectedOption} selectedOption={selectedOption}
changeDropdownOpen={setOpen} changeDropdownOpen={setOpen}
/> />
)} )}
<InputWrapper isStudent={userPrivilige === 'STUDENT'}> <InputWrapper isStudent={role === 'STUDENT'}>
<Input <Input
placeholder={`Wyszukaj ${selectedOption === 'studenci' ? 'studentów...' : 'przedmioty...'}`} placeholder={`Wyszukaj ${selectedOption === 'studenci' ? 'studentów...' : 'przedmioty...'}`}
onChange={handleChange} onChange={handleChange}

View File

@ -7,6 +7,8 @@ export interface CASContext {
logout: () => void; logout: () => void;
token: string | undefined; token: string | undefined;
refreshToken: string | undefined; refreshToken: string | undefined;
isFetchingToken: boolean;
role: string | undefined;
} }
export const CASContext = createContext<CASContext | undefined>(undefined); export const CASContext = createContext<CASContext | undefined>(undefined);
@ -19,6 +21,8 @@ export const CASProvider = ({ children }: CASProviderProps) => {
const [user, setUser] = useState<LoggedUser>(); const [user, setUser] = useState<LoggedUser>();
const [token, setToken] = useState<string | undefined>(); const [token, setToken] = useState<string | undefined>();
const [refreshToken, setRefreshToken] = useState<string | undefined>(); const [refreshToken, setRefreshToken] = useState<string | undefined>();
const [role, setRole] = useState<string | undefined>(undefined);
const [isFetchingToken, setIsFetchingToken] = useState(false);
useEffect(() => { useEffect(() => {
const login = async () => { const login = async () => {
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
@ -28,6 +32,7 @@ export const CASProvider = ({ children }: CASProviderProps) => {
} }
try { try {
if (!localStorage.getItem('userToken')) { if (!localStorage.getItem('userToken')) {
setIsFetchingToken(true);
const { data: user } = await axiosInstance.get<LoggedUser & { token: string; refreshToken: string }>( const { data: user } = await axiosInstance.get<LoggedUser & { token: string; refreshToken: string }>(
`${process.env.REACT_APP_API_URL}/token?ticket=${ticket}`, `${process.env.REACT_APP_API_URL}/token?ticket=${ticket}`,
); );
@ -36,11 +41,14 @@ export const CASProvider = ({ children }: CASProviderProps) => {
localStorage.setItem('userToken', user.token); localStorage.setItem('userToken', user.token);
localStorage.setItem('userPrivilige', user.authorityRole); localStorage.setItem('userPrivilige', user.authorityRole);
localStorage.setItem('refreshToken', user.refreshToken); localStorage.setItem('refreshToken', user.refreshToken);
setIsFetchingToken(false);
} }
const token = localStorage.getItem('userToken'); const token = localStorage.getItem('userToken');
const refreshToken = localStorage.getItem('refreshToken'); const refreshToken = localStorage.getItem('refreshToken');
const role = localStorage.getItem('userPrivilige');
token && setToken(token); token && setToken(token);
refreshToken && setRefreshToken(refreshToken); refreshToken && setRefreshToken(refreshToken);
role && setRole(role);
} catch (e) { } catch (e) {
console.log(e); console.log(e);
} }
@ -63,5 +71,9 @@ export const CASProvider = ({ children }: CASProviderProps) => {
window.location.replace(`https://cas.amu.edu.pl/cas/login?service=${window.origin}&locale=pl`); window.location.replace(`https://cas.amu.edu.pl/cas/login?service=${window.origin}&locale=pl`);
} }
return <CASContext.Provider value={{ user, token, refreshToken, logout }}>{children}</CASContext.Provider>; return (
<CASContext.Provider value={{ user, token, refreshToken, logout, isFetchingToken, role }}>
{children}
</CASContext.Provider>
);
}; };

View File

@ -37,6 +37,7 @@ axiosInstance.interceptors.response.use(
}, },
async (error) => { async (error) => {
const originalRequest = error.config; const originalRequest = error.config;
console.log("original request is: ", originalRequest)
if (error.response.status === 403 && !originalRequest._retry) { if (error.response.status === 403 && !originalRequest._retry) {
originalRequest._retry = true; originalRequest._retry = true;
const access_token = await getNewTokens(); const access_token = await getNewTokens();