Add ability to log in as sample manager

This commit is contained in:
Kacper Donat 2020-11-15 15:43:48 +01:00
parent ddf3045e92
commit 9bf5412b0d
8 changed files with 1145 additions and 11 deletions

View File

@ -12,6 +12,7 @@
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^4.0.0-alpha.55",
"@material-ui/pickers": "^3.2.10",
"@svgr/webpack": "^5.5.0",
"@types/classnames": "^2.2.10",
"@types/node": "^12.0.0",
"@types/react": "^16.9.0",

53
public/img/pg-logo.svg Normal file
View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="prefix__PGLogotyp"
viewBox="0 0 143 64"
version="1.1">
<metadata
id="metadata935">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs905">
<style
id="style903">.prefix__cls-1{fill:#fff}</style>
</defs>
<path
id="prefix__Path_108"
d="m 30.446,9.626 -3.339,2.357 1.375,1.866 2.652,-1.964 h 3.045 l 0.982,-7.17 -6.777,-1.277 -0.687,3.732 2.259,0.393 0.295,-1.473 2.357,0.491 -0.393,3.045 z"
class="prefix__cls-1"
data-name="Path 108" />
<path
id="prefix__Path_109"
d="m 111.866,11.884 2.652,1.964 1.375,-1.866 -3.241,-2.357 h -1.866 l -0.393,-3.045 2.455,-0.491 0.2,1.473 2.259,-0.393 -0.593,-3.731 -6.875,1.277 0.982,7.17 z"
class="prefix__cls-1"
data-name="Path 109" />
<path
id="prefix__Path_110"
d="m 130.036,44.884 h -2.259 v 2.259 h 7.464 l 2.159,3.045 -5.4,10.705 h -7.857 l 1.67,-3.339 h 3.241 l 3.536,-7.17 h -8.741 V 39.777 l -9.92,-7.464 2.161,-2.848 -1.866,-1.375 -3.339,4.42 v 2.554 l -11.2,2.455 -3.437,-0.982 V 34.571 H 93.991 V 49.4 L 71.4,58.045 48.813,49.4 V 32.214 h -2.259 v 1.964 l -3.634,1.08 h -10.9 v -2.847 l -3.339,-4.42 -1.866,1.375 2.161,2.848 -9.92,7.563 v 10.607 h -8.743 l 3.536,7.17 h 3.241 l 1.67,3.339 H 10.9 L 5.6,50.286 7.761,47.241 h 7.464 V 44.982 H 12.964 V 35.75 l 4.321,-3.241 V 27.795 L 21.8,24.357 20.523,22.589 27.3,17.482 35.259,21.8 v 8.45 L 44.1,31.527 45.473,27.5 h 3.536 V 8.643 h 45.179 v 21.214 h 3.536 l 1.473,4.321 8.741,-4.125 V 21.8 l 7.955,-4.321 6.777,5.107 -1.375,1.768 4.518,3.438 v 4.714 l 4.321,3.241 v 9.134 z m -86.136,-27.5 1.473,-4.42 h 1.179 v 8.054 H 44 l -6.58,4.911 v -5.3 z m -6.384,10.9 z M 46.65,25.338 H 43.9 l -1.277,3.732 -4.616,-0.589 6.875,-5.107 h 1.768 z m 58.732,3.339 -5.009,2.357 L 99.2,27.6 h -2.75 v -4.323 h 1.768 z m -7.759,-15.714 1.473,4.42 6.384,3.143 v 5.3 L 98.9,20.92 h -2.554 v -8.054 h 1.277 z m 39.977,12.573 -1.377,1.864 3.634,2.75 3.143,-4.125 v -1.864 l -6.384,-4.714 -5.009,6.482 v 3.536 l 4.223,3.143 v 4.518 l -7.857,-5.893 v -4.715 l -4.714,-3.536 1.375,-1.768 -6.679,-5.009 2.063,-1.08 5.893,4.42 -1.375,1.768 4.223,3.241 1.375,-1.866 -4.223,-3.143 1.375,-1.768 -5.107,-3.83 v -2.652 l 6.286,4.714 -1.375,1.768 3.438,2.554 1.375,-1.866 -3.437,-2.554 1.375,-1.768 -7.761,-5.795 V 5.795 l 9.036,6.777 -1.375,1.768 2.554,1.964 1.375,-1.866 -2.554,-1.964 1.375,-1.768 -10.214,-7.76 V 0 h -2.259 v 2.455 l -3.634,0.688 0.393,2.259 3.241,-0.589 v 7.857 l -6.187,3.339 -2.848,-2.161 -1.375,1.866 1.964,1.473 -3.732,2.063 -6.973,-3.437 L 99.1,10.705 H 96.25 V 6.384 h -49.6 v 4.321 H 43.8 L 42.032,15.812 35.063,19.25 31.33,17.188 33.294,15.715 31.92,13.848 29.072,16.009 22.884,12.67 V 4.813 L 26.125,5.402 26.518,3.143 22.884,2.456 V 0 h -2.259 v 2.946 l -10.214,7.854 1.375,1.768 -2.554,1.964 1.375,1.868 2.554,-1.964 -1.375,-1.766 9.036,-6.777 v 2.652 l -7.759,5.795 1.375,1.768 -3.438,2.553 1.375,1.866 3.438,-2.554 -1.375,-1.768 6.286,-4.714 v 2.652 l -5.107,3.83 1.375,1.768 -4.223,3.143 1.375,1.67 4.223,-3.241 -1.277,-1.67 5.893,-4.42 2.063,1.08 -6.679,5.009 1.375,1.768 -4.714,3.536 V 31.33 L 7.17,37.223 v -4.518 l 4.223,-3.143 V 25.83 L 6.384,19.348 0,24.063 v 1.866 L 3.143,30.054 6.777,27.304 5.5,25.536 3.634,26.911 2.357,25.143 5.893,22.491 9.036,26.616 v 1.768 l -4.223,3.143 v 6.482 l 1.866,2.455 4.027,-3.045 v 7.563 H 6.58 L 2.946,50.089 9.429,63.25 h 11.785 v -2.357 l -2.75,-5.6 h -3.241 l -1.277,-2.554 h 7.268 V 40.955 L 23.669,39.187 33,43.9 v 6.286 l -2.161,3.144 2.061,4.224 h 3.241 l 1.67,3.339 h -7.856 l -4.027,-8.152 1.964,-2.848 v -5.009 h -4.321 v 2.259 h 2.063 v 2.063 l -2.357,3.339 5.3,10.607 h 11.789 v -2.357 l -2.75,-5.6 h -3.241 l -0.884,-1.768 1.866,-2.652 V 42.33 l -9.527,-4.91 3.929,-2.946 v 2.848 H 43.411 L 46.652,36.34 V 50.679 L 71.5,60.205 96.348,50.678 V 38.795 l 3.438,0.982 13.554,-2.946 V 34.67 l 3.929,2.946 -9.527,4.911 v 8.446 l 1.866,2.652 -0.884,1.768 h -3.241 l -2.75,5.6 v 2.357 h 11.786 l 5.3,-10.607 -2.355,-3.343 v -2.061 h 2.062 V 45.08 h -4.321 v 5.009 l 1.964,2.848 -4.027,8.152 h -7.857 l 1.67,-3.339 H 110.2 L 112.263,53.527 110,50.384 V 44.1 l 9.33,-4.714 2.455,1.768 v 11.784 h 7.268 l -1.277,2.554 h -3.241 l -2.75,5.6 v 2.357 h 11.786 l 6.482,-13.161 -3.634,-5.107 h -4.125 v -7.565 l 4.027,3.045 1.866,-2.455 v -6.483 l -4.223,-3.143 v -1.768 l 3.143,-4.125 3.536,2.652 -1.277,1.67 z"
class="prefix__cls-1"
data-name="Path 110" />
<path
id="prefix__Path_111"
d="m 63.25,20.822 a 1.2,1.2 0 0 0 -0.884,-0.295 h -2.357 v 3.045 h 2.357 a 1.85,1.85 0 0 0 0.786,-0.2 0.658,0.658 0 0 0 0.393,-0.687 V 21.607 A 0.658,0.658 0 0 0 63.25,20.821"
class="prefix__cls-1"
data-name="Path 111" />
<path
id="prefix__Path_112"
d="m 86.331,21.215 v 2.063 h -8.349 v -2.063 l -0.393,-3.437 2.063,1.375 -0.491,1.964 h 2.455 l -0.786,-1.964 1.375,-2.259 1.375,2.259 -0.786,1.964 h 2.456 l -0.491,-1.964 2.063,-1.375 z m -0.589,10.116 -2.652,-0.295 0.393,2.652 h -2.554 l 0.393,-2.652 -2.652,0.295 v -2.554 l 2.652,0.393 -0.393,-2.652 h 2.554 l -0.393,2.554 2.652,-0.295 z m 0,10.313 -2.652,-0.393 0.393,2.652 h -2.554 l 0.393,-2.652 -2.652,0.295 v -2.555 l 2.652,0.393 -0.393,-2.554 h 2.554 l -0.393,2.554 2.652,-0.295 v 2.554 z M 72.286,44.102 H 70.813 V 18.759 h 1.473 z M 65.411,22.786 a 3.531,3.531 0 0 1 -0.2,1.08 2.648,2.648 0 0 1 -0.687,0.786 3.072,3.072 0 0 1 -0.982,0.491 4.221,4.221 0 0 1 -1.179,0.2 h -2.354 v 3.536 h -1.768 v -9.727 h 4.129 a 4.93,4.93 0 0 1 1.179,0.2 3.072,3.072 0 0 1 0.982,0.491 1.527,1.527 0 0 1 0.589,0.786 2.127,2.127 0 0 1 0.2,1.179 v 0.982 z m -0.295,18.955 a 3.981,3.981 0 0 1 -0.884,0.491 c -0.295,0.1 -0.589,0.295 -0.884,0.393 a 2.868,2.868 0 0 1 -0.884,0.2 3.028,3.028 0 0 1 -0.982,0.1 5.944,5.944 0 0 1 -1.473,-0.2 2.24,2.24 0 0 1 -1.179,-0.589 3.845,3.845 0 0 1 -0.786,-0.982 3.137,3.137 0 0 1 -0.295,-1.375 v -3.734 a 3.137,3.137 0 0 1 0.295,-1.375 3.845,3.845 0 0 1 0.786,-0.982 3.319,3.319 0 0 1 1.179,-0.589 7.581,7.581 0 0 1 1.473,-0.2 4.758,4.758 0 0 1 1.768,0.295 3.7,3.7 0 0 1 1.473,0.884 l -0.687,1.277 a 7.326,7.326 0 0 0 -1.179,-0.688 3.024,3.024 0 0 0 -1.277,-0.295 2.163,2.163 0 0 0 -0.786,0.1 4.787,4.787 0 0 0 -0.687,0.295 c -0.2,0.1 -0.295,0.295 -0.491,0.491 a 1.42,1.42 0 0 0 -0.2,0.688 v 3.732 a 1.42,1.42 0 0 0 0.2,0.688 1.184,1.184 0 0 0 0.491,0.491 4.788,4.788 0 0 0 0.688,0.295 3.585,3.585 0 0 0 1.67,0 3.489,3.489 0 0 0 0.884,-0.393 V 38.602 H 61.97 v -1.28 h 3.241 v 4.42 z M 51.17,10.902 v 36.83 l 20.33,7.857 20.33,-7.857 v -36.83 z"
class="prefix__cls-1"
data-name="Path 112" />
</svg>

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@ -15,6 +15,7 @@ import { getLocale, Locale } from "@/state/reducer/settings";
import i18n from "@/i18n";
import moment from "moment-timezone";
import { Container } from "@material-ui/core";
import { useCurrentUser } from "@/hooks";
const UserMenu = (props: HTMLProps<HTMLUListElement>) => {
const student = useSelector<AppState, Student>(state => state.student as Student);
@ -62,6 +63,7 @@ const LanguageSwitcher = ({ className, ...props }: HTMLProps<HTMLUListElement>)
function App() {
const { t } = useTranslation();
const locale = useSelector<AppState, Locale>(state => getLocale(state.settings));
const user = useCurrentUser();
useEffect(() => {
i18n.changeLanguage(locale);
@ -104,7 +106,7 @@ function App() {
<footer className="footer">
<Container style={{ display: 'flex', alignItems: "center" }}>
<ul className="footer__menu">
<li><Link to="/management">{ t("management") }</Link></li>
{ user?.isManager && <li><Link to="/management">{ t("management") }</Link></li> }
</ul>
<div className="footer__copyright">{ t('copyright', { date: moment() }) }</div>
</Container>

View File

@ -1,6 +1,6 @@
import React, { Dispatch, useEffect } from "react";
import { Page } from "@/pages/base";
import { Button, CircularProgress, Container, Typography } from "@material-ui/core";
import { Button, CircularProgress, Container, SvgIcon, Typography } from "@material-ui/core";
import { Action, StudentActions, useDispatch } from "@/state/actions";
import { Route, Switch, useHistory, useLocation, useRouteMatch } from "react-router-dom";
import { route } from "@/routing";
@ -12,13 +12,22 @@ import { UserActions } from "@/state/actions/user";
import { getAuthorizeUrl } from "@/api/user";
import { useTranslation } from "react-i18next";
import { Loading } from "@/components/loading";
import GUTLogo from "!@svgr/webpack!@/../public/img/pg-logo.svg";
const authorizeUser = (code?: string) => async (dispatch: Dispatch<Action>, getState: () => AppState): Promise<void> => {
type AuthorizeUserOptions = {
isStudent?: boolean;
isManager?: boolean;
}
const authorizeUser = (code?: string, { isStudent = false, isManager = false }: AuthorizeUserOptions = { isStudent: true }) => async (dispatch: Dispatch<Action>, getState: () => AppState): Promise<void> => {
const token = await api.user.login(code);
dispatch({
type: UserActions.Login,
token,
isStudent,
isManager,
})
const student = await api.student.current();
@ -36,7 +45,13 @@ export const UserLoginPage = () => {
const query = new URLSearchParams(useLocation().search);
const { t } = useTranslation();
const handleSampleLogin = async () => {
const handleSampleAdminLogin = async () => {
await dispatch(authorizeUser(undefined, { isManager: true }));
history.push(route("management:index"));
}
const handleSampleStudentLogin = async () => {
await dispatch(authorizeUser());
history.push(route("home"));
@ -46,7 +61,7 @@ export const UserLoginPage = () => {
history.push(route("user_login") + "/pg");
}
const classes = useVerticalSpacing(3);
const classes = useVerticalSpacing(2);
useEffect(() => {
(async function() {
@ -61,14 +76,21 @@ export const UserLoginPage = () => {
return <Page>
<Page.Header maxWidth="md">
<Page.Title>Zaloguj się</Page.Title>
<Page.Title>{ t("login") }</Page.Title>
</Page.Header>
<Container>
<Switch>
<Route path={match.path} exact>
<Container maxWidth="md" className={ classes.root }>
<Button fullWidth onClick={ handlePgLogin } variant="contained" color="primary">Zaloguj się z pomocą konta PG</Button>
<Button fullWidth onClick={ handleSampleLogin } variant="contained" color="secondary">Zaloguj jako przykładowy student</Button>
<Button fullWidth onClick={ handlePgLogin } variant="contained" color="primary" startIcon={
// @ts-ignore
<GUTLogo style={{ height: "1.25rem" }} viewBox="0 0 144 64" />
}>
{ t("login-as.gut-account") }
</Button>
<Typography variant="subtitle2">{ t("login-as.sample") }</Typography>
<Button fullWidth onClick={ handleSampleStudentLogin } variant="contained" color="secondary">{ t("login-as.sample-student")}</Button>
<Button fullWidth onClick={ handleSampleAdminLogin } variant="contained" color="secondary">{ t("login-as.sample-manager")}</Button>
</Container>
</Route>
<Route path={`${match.path}/pg`} render={ () => {

View File

@ -7,6 +7,8 @@ export enum UserActions {
export interface LoginAction extends Action<UserActions.Login> {
token: string;
isStudent: boolean;
isManager: boolean;
}
export type LogoutAction = Action<UserActions.Logout>;

View File

@ -4,11 +4,13 @@ export type UserState = {
loggedIn: boolean;
token?: string;
isManager: boolean;
isStudent: boolean;
}
const initialUserState: UserState = {
loggedIn: false,
isManager: false,
isStudent: false,
}
const userReducer = (state: UserState = initialUserState, action: UserAction): UserState => {
@ -18,7 +20,8 @@ const userReducer = (state: UserState = initialUserState, action: UserAction): U
...state,
loggedIn: true,
token: action.token,
isManager: true,
isManager: action.isManager,
isStudent: action.isManager,
}
case UserActions.Logout:

View File

@ -5,6 +5,11 @@ login: zaloguj się
login-in-progress: Logowanie w toku, proszę czekać...
logout: wyloguj się
logged-in-as: zalogowany jako <1>{{ name }}</1>
login-as:
sample: "Przykładowe konta"
gut-account: "Zaloguj z pomocą konta politechnicznego"
sample-student: "Zaloguj jako przykładowy student"
sample-manager: "Zaloguj jako przykładowy pełnomocnik/administrator"
until: do {{ date, DD MMMM YYYY }}
not-before: od {{ date, DD MMMM YYYY }}

1050
yarn.lock

File diff suppressed because it is too large Load Diff