Skip to content
This repository was archived by the owner on Apr 5, 2024. It is now read-only.

Commit 166d231

Browse files
authored
remove registration from navbar when you are not admin (#194)
1 parent 1348304 commit 166d231

File tree

4 files changed

+155
-77
lines changed

4 files changed

+155
-77
lines changed

src/background/api/userInformation.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,33 @@ import Axios, { AxiosResponse } from "axios";
33
import { hostname, userPath } from "./api";
44

55
import store from "../redux/store";
6-
import {updateUser} from "../redux/actions/user";
7-
import {UserState} from "../redux/actions/userTypes";
6+
import { updateUser } from "../redux/actions/user";
7+
import { UserState } from "../redux/actions/userTypes";
88

99
export interface UserInformation {
1010
userId: number | null;
1111
username?: string | null;
12-
groups?: number[]|null;
12+
groups?: string[] | null;
1313
password?: string;
1414
confirmationPassword?: string;
1515
}
1616

17-
export const changeUserInformation = (userWithNewInformation: UserInformation): Promise<UserState> => {
18-
console.log("[API] userinformation: User given to update user api:")
19-
console.log(userWithNewInformation)
17+
export const changeUserInformation = (
18+
userWithNewInformation: UserInformation
19+
): Promise<UserState> => {
20+
console.log("[API] userinformation: User given to update user api:");
21+
console.log(userWithNewInformation);
2022
return new Promise((resolve, reject) => {
21-
return Axios.put(`${hostname}${userPath}/${userWithNewInformation.userId}/edit`, userWithNewInformation)
23+
return Axios.put(
24+
`${hostname}${userPath}/${userWithNewInformation.userId}/edit`,
25+
userWithNewInformation
26+
)
2227
.then((response: AxiosResponse<UserState>) => {
2328
store.dispatch(updateUser(JSON.parse(response.config.data)));
24-
resolve(response.data)
29+
resolve(response.data);
2530
})
2631
.catch((error) => {
2732
reject(error.response?.data?.message);
2833
});
29-
})
30-
};
34+
});
35+
};
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
export const UPDATE_USER = "UPDATE_USER";
22

33
export interface UserState {
4-
userId: number | null;
5-
username: string | null;
6-
groups: number[];
4+
userId: number | null;
5+
username: string | null;
6+
groups: string[];
77
}
88

9-
109
export interface UpdateUser {
11-
type: typeof UPDATE_USER;
12-
payload: UserState;
10+
type: typeof UPDATE_USER;
11+
payload: UserState;
1312
}
1413

1514
export type UserActionTypes = UpdateUser;

src/components/basicElements/topArea/Header.tsx

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@ import React, { ReactElement } from "react";
22
import { useHistory } from "react-router-dom";
33
import { redirect } from "../../../background/methods/redirect";
44
import logo from "../../../assets/images/logos/logo.png";
5-
import { Container, Nav, Navbar, NavbarBrand, NavDropdown } from "react-bootstrap";
5+
import {
6+
Container,
7+
Nav,
8+
Navbar,
9+
NavbarBrand,
10+
NavDropdown
11+
} from "react-bootstrap";
612
import { SystemState } from "../../../background/redux/actions/sytemState";
713
import { connect, ConnectedProps } from "react-redux";
814
import { logout } from "../../../background/api/auth";
@@ -17,7 +23,8 @@ export interface navBarElement_Interface {
1723
}
1824

1925
const mapState = (state: SystemState) => ({
20-
username: state.user.username
26+
username: state.user.username,
27+
groups: state.user.groups
2128
});
2229

2330
const connector = connect(mapState);
@@ -39,15 +46,17 @@ function Header(props: PropsFromRedux): ReactElement {
3946
text: "Files",
4047
link: "/file",
4148
logo: null
42-
},
43-
{
49+
}
50+
];
51+
52+
if (props.groups.includes("ADMIN")) {
53+
navBarElements.push({
4454
name: "registration",
4555
text: "Registration",
4656
link: "/registration",
4757
logo: null
48-
}
49-
];
50-
58+
});
59+
}
5160
const final: ReactElement[] = [];
5261
navBarElements.forEach((element) => {
5362
final.push(
@@ -70,7 +79,6 @@ function Header(props: PropsFromRedux): ReactElement {
7079
<header>
7180
<Navbar bg="primary" expand="lg" sticky="top">
7281
<Container>
73-
7482
<NavbarBrand
7583
href="/start"
7684
onClick={(event: any) => {
@@ -91,11 +99,18 @@ function Header(props: PropsFromRedux): ReactElement {
9199
{props.username && (
92100
<Nav className="navbar-collapse justify-content-end">
93101
{final}
94-
<NavDropdown title={props.username} id="basic-nav-dropdown">
102+
<NavDropdown
103+
title={props.username}
104+
id="basic-nav-dropdown"
105+
>
95106
<NavDropdown.Item
96107
href="/profile"
97108
onClick={(event: any) => {
98-
redirect(history, "/profile", event);
109+
redirect(
110+
history,
111+
"/profile",
112+
event
113+
);
99114
}}
100115
>
101116
Profile
@@ -114,8 +129,7 @@ function Header(props: PropsFromRedux): ReactElement {
114129
</Container>
115130
</Navbar>
116131
</header>
117-
)
118-
;
132+
);
119133
}
120134

121135
export default connector(Header);
Lines changed: 109 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,53 @@
1-
import React, {ReactElement, useState} from "react";
2-
import {Alert, Button, Container} from "react-bootstrap";
3-
import UserInformationInput, {UserInformationInputInterface} from "./UserInformationInput";
4-
import {useSelector} from "react-redux";
5-
import {RootState} from "../../../background/redux/store";
6-
import {DEFAULT_ALERT_DURATION, MIN_PASSWORD_LENGTH} from "../../../background/constants";
7-
import {changeUserInformation, UserInformation} from "../../../background/api/userInformation";
8-
import {notMinStrLength} from "../../../background/methods/checkInput";
1+
import React, { ReactElement, useState } from "react";
2+
import { Alert, Button, Container } from "react-bootstrap";
3+
import UserInformationInput, {
4+
UserInformationInputInterface
5+
} from "./UserInformationInput";
6+
import { useSelector } from "react-redux";
7+
import { RootState } from "../../../background/redux/store";
8+
import {
9+
DEFAULT_ALERT_DURATION,
10+
MIN_PASSWORD_LENGTH
11+
} from "../../../background/constants";
12+
import {
13+
changeUserInformation,
14+
UserInformation
15+
} from "../../../background/api/userInformation";
16+
import { notMinStrLength } from "../../../background/methods/checkInput";
917
import edit_svg from "../../../assets/images/icons/material.io/edit_white_24dp.svg";
10-
import {hashPassword} from "../../../background/methods/passwords";
11-
18+
import { hashPassword } from "../../../background/methods/passwords";
1219

1320
export default function Profile(): ReactElement {
1421
const [isEditing, setIsEditing] = useState<boolean>(false);
1522
const user = useSelector((state: RootState) => state.user);
16-
const [alertMessage, setAlertMessage] = useState<string>("Error 404: No Message found.");
17-
const [alertVariant, setAlertColor] = useState<"primary" | "secondary" | "success" | "danger" | "warning" | "info" | "light" | "dark">("success");
23+
const [alertMessage, setAlertMessage] = useState<string>(
24+
"Error 404: No Message found."
25+
);
26+
const [alertVariant, setAlertColor] = useState<
27+
| "primary"
28+
| "secondary"
29+
| "success"
30+
| "danger"
31+
| "warning"
32+
| "info"
33+
| "light"
34+
| "dark"
35+
>("success");
1836
const [alertVisibility, setAlertVisibility] = useState<boolean>(false);
1937

20-
const handleAlertVisibility = (duration: number, color: "primary" | "secondary" | "success" | "danger" | "warning" | "info" | "light" | "dark", message: string) => {
38+
const handleAlertVisibility = (
39+
duration: number,
40+
color:
41+
| "primary"
42+
| "secondary"
43+
| "success"
44+
| "danger"
45+
| "warning"
46+
| "info"
47+
| "light"
48+
| "dark",
49+
message: string
50+
) => {
2151
if (!alertVisibility) {
2252
setAlertMessage(message);
2353
setAlertColor(color);
@@ -26,99 +56,129 @@ export default function Profile(): ReactElement {
2656
setAlertVisibility(false);
2757
}, duration);
2858
}
29-
}
59+
};
3060

3161
function changeEditMode(): void {
32-
console.log("[PROFILE] changedEditMode")
33-
setIsEditing(!isEditing)
62+
console.log("[PROFILE] changedEditMode");
63+
setIsEditing(!isEditing);
3464
}
3565

3666
const handleSubmit = async (inputUser: UserInformationInputInterface) => {
37-
console.log("[PROFILE] handleSubmit")
67+
console.log("[PROFILE] handleSubmit");
3868
let newUser: UserInformation = {
3969
groups: user.groups,
4070
userId: user.userId
41-
}
71+
};
4272
if (!inputUser.username) {
43-
handleAlertVisibility(DEFAULT_ALERT_DURATION, "danger", "Error: Please choose an username.")
73+
handleAlertVisibility(
74+
DEFAULT_ALERT_DURATION,
75+
"danger",
76+
"Error: Please choose an username."
77+
);
4478
return;
4579
}
4680
newUser["username"] = inputUser.username;
4781
if (inputUser.password || inputUser.passwordConfirmation) {
4882
if (inputUser.password !== inputUser.passwordConfirmation) {
49-
handleAlertVisibility(DEFAULT_ALERT_DURATION, "danger", "Error: Password and password confirmation must match.")
83+
handleAlertVisibility(
84+
DEFAULT_ALERT_DURATION,
85+
"danger",
86+
"Error: Password and password confirmation must match."
87+
);
5088
return;
5189
}
52-
if (inputUser.password.match(/\d/) == null || inputUser.password.match(/[a-z]/) == null || inputUser.password.match(/[A-Z]/) == null || notMinStrLength(inputUser.password, MIN_PASSWORD_LENGTH)) {
53-
handleAlertVisibility(DEFAULT_ALERT_DURATION, "danger", "Error: Please pay attention to the notes below the input fields.")
90+
if (
91+
inputUser.password.match(/\d/) == null ||
92+
inputUser.password.match(/[a-z]/) == null ||
93+
inputUser.password.match(/[A-Z]/) == null ||
94+
notMinStrLength(inputUser.password, MIN_PASSWORD_LENGTH)
95+
) {
96+
handleAlertVisibility(
97+
DEFAULT_ALERT_DURATION,
98+
"danger",
99+
"Error: Please pay attention to the notes below the input fields."
100+
);
54101
return;
55102
}
56103
newUser["password"] = await hashPassword(inputUser.password);
57104
newUser["confirmationPassword"] = newUser["password"];
58105
}
59106

60107
await changeUserInformation(newUser)
61-
.then(res => {
62-
changeEditMode()
63-
handleAlertVisibility(DEFAULT_ALERT_DURATION, "success", "Worked: " + (res));
64-
})
65-
.catch(err => {
66-
console.log("Error:" + err)
67-
handleAlertVisibility(DEFAULT_ALERT_DURATION, "danger", "Error: " + err)
108+
.then((res) => {
109+
changeEditMode();
110+
handleAlertVisibility(
111+
DEFAULT_ALERT_DURATION,
112+
"success",
113+
"Worked: " + res
114+
);
68115
})
69-
}
116+
.catch((err) => {
117+
console.log("Error:" + err);
118+
handleAlertVisibility(
119+
DEFAULT_ALERT_DURATION,
120+
"danger",
121+
"Error: " + err
122+
);
123+
});
124+
};
70125

71126
function EditProfile(): ReactElement {
72127
return (
73128
<>
74129
<UserInformationInput
75130
triggerAlert={handleAlertVisibility}
76131
submitFunction={handleSubmit}
77-
presets={{username: user.username ?? "", password: ""}}
132+
presets={{ username: user.username ?? "", password: "" }}
78133
/>
79-
<Alert variant={alertVariant} onClose={() => setAlertVisibility(false)} show={alertVisibility}
80-
dismissible>
134+
<Alert
135+
variant={alertVariant}
136+
onClose={() => setAlertVisibility(false)}
137+
show={alertVisibility}
138+
dismissible
139+
>
81140
<p>{alertMessage}</p>
82141
</Alert>
83142
</>
84-
)
143+
);
85144
}
86145

87146
function DisplayProfile(): ReactElement {
88147
return (
89148
<div className="profile-information-display p-0 w-100">
90-
<h2 className="h3 pb-3">
91-
{user.username}
92-
</h2>
149+
<h2 className="h3 pb-3">{user.username}</h2>
93150
<dl>
94151
<dt>Username</dt>
95152
<dd>{user.username}</dd>
96153
<dt>Groups</dt>
97-
<dd>{user.groups?.map((value: number) => {
98-
return value + " "
99-
})}
154+
<dd>
155+
{user.groups?.map((value: string) => {
156+
return value + " ";
157+
})}
100158
</dd>
101159
</dl>
102160
</div>
103-
)
161+
);
104162
}
105163

106164
return (
107165
<Container className="page-content">
108166
<div className="px-1 w-100 mt-1 mb-3 ">
109167
<div className="w-100 title-action">
110-
<h1 className="mr-1 h4">
111-
My Profile
112-
</h1>
113-
<Button
114-
onClick={changeEditMode}
115-
>
116-
{!isEditing && <img src={edit_svg} alt={"edit icon"} className="pr-2"/>}
168+
<h1 className="mr-1 h4">My Profile</h1>
169+
<Button onClick={changeEditMode}>
170+
{!isEditing && (
171+
<img
172+
src={edit_svg}
173+
alt={"edit icon"}
174+
className="pr-2"
175+
/>
176+
)}
117177
{isEditing ? "Cancel" : "Edit"}
118178
</Button>
119179
</div>
120180
</div>
121-
{isEditing ? <EditProfile/> : <DisplayProfile/>}
181+
{isEditing ? <EditProfile /> : <DisplayProfile />}
122182
</Container>
123183
);
124184
}

0 commit comments

Comments
 (0)