Skip to content

Commit 817a443

Browse files
authored
Merge pull request #20 from DevOps-Cloud-Team5/SCRUM-39-profile-page
Scrum 39 Profile page and register page
2 parents 3ab0594 + ba637e2 commit 817a443

File tree

12 files changed

+388
-9684
lines changed

12 files changed

+388
-9684
lines changed

package-lock.json

-9,648
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/pages/create_user/create.css

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
.login-container {
2+
position: fixed;
3+
width: 100%;
4+
height: 100%; /* Adjust height to occupy half of the screen */
5+
display: flex;
6+
flex-direction: column; /* Align items vertically */
7+
justify-content: center; /* Align items to the left horizontally */
8+
padding: 20px;
9+
background-color: #f9f9f9;
10+
overflow: auto; /* Add overflow to enable scrolling if content exceeds viewport */
11+
}
12+
13+
.login-title {
14+
text-align: center;
15+
margin: 20px;
16+
17+
color: #00aaff;
18+
}
19+
20+
.login-form {
21+
width: 100%;
22+
text-align: center;
23+
margin-bottom: 100px;
24+
top: 200;
25+
margin-top: 30px;
26+
}
27+
28+
.remember {
29+
color: black;
30+
text-align: center;
31+
justify-content: center;
32+
margin-right: 55px;
33+
}
34+
35+
.login-form input,
36+
.login-form button {
37+
top: 500px;
38+
margin-top: 10px;
39+
align-items: center;
40+
}
41+
42+
.login-form button {
43+
padding: 10px;
44+
background-color: #00a2ff;
45+
color: #ffffff;
46+
border: none;
47+
border-radius: 5px;
48+
cursor: pointer;
49+
width: 9%;
50+
}
51+
52+
.login-form button:hover {
53+
background-color: #00aaff;
54+
}
55+
.forget {
56+
color: black;
57+
text-align: center;
58+
justify-content: center;
59+
margin-left: 300px;
60+
}

src/pages/create_user/index.tsx

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
import React, { useState } from "react";
2+
3+
import Button from "@mui/material/Button";
4+
import TextField from "@mui/material/TextField";
5+
import Container from "@mui/material/Container";
6+
import Avatar from "@mui/material/Avatar";
7+
import Typography from "@mui/material/Typography";
8+
import { Box, MenuItem, Select } from "@mui/material";
9+
import HowToRegOutlinedIcon from "@mui/icons-material/HowToRegOutlined";
10+
11+
import RootPage from "../root";
12+
import "./create.css"; // Import CSS file for additional styling
13+
import { post_db } from "../../utils";
14+
15+
const CreateUser = () => {
16+
// const navigate = useNavigate();
17+
const [regStatus, setRegStatus] = useState("");
18+
19+
const handleTokenResponse = (data: any, event : React.FormEvent<HTMLFormElement>) => {
20+
console.log(data)
21+
if (!("username" in data) || (typeof data["username"] !== "string")) {
22+
setRegStatus("failed");
23+
return;
24+
}
25+
else {
26+
setRegStatus("success");
27+
}
28+
// event.currentTarget.reset()
29+
// navigate(0);
30+
// navigate("/home", { replace: true });
31+
};
32+
33+
// TODO: Add first and last name validation
34+
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
35+
setRegStatus("submitting");
36+
event.preventDefault();
37+
const data = new FormData(event.currentTarget);
38+
const first_name = data.get("first_name");
39+
const last_name = data.get("last_name");
40+
41+
let username = data.get("username");
42+
let email = data.get("email");
43+
44+
if (username == "") username = first_name + "." + last_name;
45+
if (email == "") email = first_name + "." + last_name + "@uni.org";
46+
47+
if (username !== null) username = username.toString().toLowerCase()
48+
if (email !== null) email = email.toString().toLowerCase()
49+
50+
post_db(
51+
"user/register/",
52+
JSON.stringify({
53+
username: username,
54+
password: data.get("password"),
55+
first_name: first_name,
56+
last_name: last_name,
57+
email: email,
58+
role: data.get("role")
59+
})
60+
)
61+
.then((resp) => (resp.json()))
62+
.then((data) => handleTokenResponse(data, event))
63+
.catch((error) => console.log(error));
64+
};
65+
66+
return (
67+
<RootPage>
68+
<Container component="main" maxWidth="xs">
69+
<Box
70+
sx={{
71+
marginTop: 8,
72+
display: "flex",
73+
flexDirection: "column",
74+
alignItems: "center"
75+
}}
76+
>
77+
<Avatar sx={{ m: 1, bgcolor: "secondary.main" }}>
78+
<HowToRegOutlinedIcon />
79+
</Avatar>
80+
<Typography component="h1" variant="h5">
81+
Register User
82+
</Typography>
83+
<Box
84+
component="form"
85+
onSubmit={handleSubmit}
86+
noValidate
87+
sx={{ mt: 1 }}
88+
color={"primary"}
89+
>
90+
<TextField
91+
margin="normal"
92+
required
93+
fullWidth
94+
id="first_name"
95+
label="First Name"
96+
name="first_name"
97+
autoComplete="first_name"
98+
autoFocus
99+
color="primary"
100+
/>
101+
<TextField
102+
margin="normal"
103+
required
104+
fullWidth
105+
id="last_name"
106+
label="Last Name"
107+
name="last_name"
108+
autoComplete="last_name"
109+
autoFocus
110+
color="primary"
111+
/>
112+
<TextField
113+
margin="normal"
114+
required
115+
fullWidth
116+
name="password"
117+
label="Password"
118+
type="password"
119+
id="password"
120+
autoComplete="current-password"
121+
/>
122+
<TextField
123+
margin="normal"
124+
fullWidth
125+
id="username"
126+
label="Username"
127+
name="username"
128+
autoComplete="username"
129+
autoFocus
130+
color="primary"
131+
/>
132+
<TextField
133+
margin="normal"
134+
fullWidth
135+
id="email"
136+
label="Email"
137+
name="email"
138+
autoComplete="email"
139+
autoFocus
140+
color="primary"
141+
/>
142+
<Select
143+
color="primary"
144+
required
145+
fullWidth
146+
id="role"
147+
name="role"
148+
autoComplete="role"
149+
autoFocus
150+
label="Role"
151+
defaultValue="student"
152+
>
153+
<MenuItem value="student">Student</MenuItem>
154+
<MenuItem value="teacher">Teacher</MenuItem>
155+
<MenuItem value="admin">Admin</MenuItem>
156+
</Select>
157+
158+
{regStatus === "success" && (
159+
<Typography variant="body1" color="success">Registration successful!</Typography>
160+
)}
161+
{regStatus === "failed" && (
162+
<Typography variant="body1" color="error">Registration failed. Please try again.</Typography>
163+
)}
164+
165+
<Button
166+
type="submit"
167+
fullWidth
168+
variant="contained"
169+
sx={{ mt: 3, mb: 2 }}
170+
>
171+
Create
172+
</Button>
173+
</Box>
174+
</Box>
175+
</Container>
176+
</RootPage>
177+
);
178+
};
179+
180+
export default CreateUser;

src/pages/home/index.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const HomePage: FC = () => (
77
<Rootpage>
88
<Box
99
sx={{
10-
backgroundImage: `url(${backgroundImage})`,
10+
// backgroundImage: `url(${backgroundImage})`,
1111
backgroundSize: "cover",
1212
backgroundPosition: "center",
1313
color: "white",
@@ -21,10 +21,11 @@ const HomePage: FC = () => (
2121
}}
2222
>
2323
<Typography variant="h1" component="h1" gutterBottom>
24-
Welcome to Attendunce
24+
Attendunce Dashboard
2525
</Typography>
2626
<Typography variant="subtitle1" gutterBottom>
27-
The ultimate attendance tracking solution
27+
Overview of Schedule |
28+
Attendence Overview
2829
</Typography>
2930
</Box>
3031
</Rootpage>

src/pages/login/index.tsx

-5
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,6 @@ const SignIn = () => {
132132
Forgot password?
133133
</Link>
134134
</Grid>
135-
<Grid item>
136-
<Link href="#" variant="body2">
137-
{"Don't have an account? Sign Up"}
138-
</Link>
139-
</Grid>
140135
</Grid>
141136
</Box>
142137
</Box>

src/pages/people/index.tsx

+41-8
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { User } from "../../types/common";
88
import { Button, IconButton, Typography } from "@mui/material";
99
import { styled } from "@mui/material/styles";
1010
import MoreVertIcon from "@mui/icons-material/MoreVert";
11+
import AddCircleOutlineIcon from "@mui/icons-material/AddCircleOutline";
1112
import Avatar from "@mui/material/Avatar";
1213

1314
const People = () => {
@@ -26,8 +27,8 @@ const People = () => {
2627
useEffect(() => {
2728
const fetchUsers = async () => {
2829
try {
29-
const students_query = await getUserRole("students");
30-
const teachers_query = await getUserRole("teachers");
30+
const students_query = await getUserRole("student");
31+
const teachers_query = await getUserRole("teacher");
3132
if ("code" in students_query || "code" in teachers_query) {
3233
// Not authenticated anymore
3334
deleteAuthCookies();
@@ -40,13 +41,13 @@ const People = () => {
4041
"error" in students_query || "detail" in students_query
4142
)
4243
? students_query
43-
: {};
44+
: [];
4445
const teachers = !(
4546
"error" in teachers_query || "detail" in teachers_query
4647
)
4748
? teachers_query
48-
: {};
49-
setAllUsers(students.concat(teachers));
49+
: [];
50+
setAllUsers(teachers.concat(students));
5051
} catch (error) {
5152
console.error("Error fetching profile:", error);
5253
// Show error on frontend
@@ -87,12 +88,33 @@ const People = () => {
8788
}
8889
});
8990

91+
const handleNewUserClick = () => {
92+
navigate(`/create_user`);
93+
};
94+
95+
const handleProfileClick = (username: string) => {
96+
navigate(`/profile/${username}`);
97+
};
98+
9099
return (
91100
<RootPage>
92-
<Container component="main">
101+
<Container component="main" className="mainComponent">
93102
<Typography variant="h4" gutterBottom>
94103
People
104+
{IsAdmin() ? (
105+
<IconButton
106+
onClick={() => handleNewUserClick()}
107+
style={{
108+
marginLeft: "2%",
109+
color: "white",
110+
backgroundColor: "rgba(255, 255, 255, 0.5)"
111+
}}
112+
>
113+
<AddCircleOutlineIcon style={{ fontSize: "1em" }} />
114+
</IconButton>
115+
) : null}
95116
</Typography>
117+
96118
<StyledTable>
97119
<thead>
98120
<tr>
@@ -121,9 +143,20 @@ const People = () => {
121143
/>
122144
</td>
123145
<td>
124-
<Button>{`${user.first_name} ${user.last_name}`}</Button>
146+
<Button
147+
style={{
148+
color: "white",
149+
textTransform: "none",
150+
fontSize: "1em"
151+
}}
152+
onClick={() =>
153+
handleProfileClick(user.username)
154+
}
155+
>
156+
{`${user.first_name} ${user.last_name}`}
157+
</Button>
125158
</td>
126-
<td>{user.role}</td>
159+
<td style={{ fontSize: "1em" }}>{user.role}</td>
127160
{IsAdmin() ? (
128161
<td className="actions-icon">
129162
<IconButton>

src/pages/people/people.css

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.mainComponent {
2+
background: rgba(
3+
255,
4+
255,
5+
255,
6+
0.1
7+
); /* Semi-transparent white for profile background */
8+
backdrop-filter: blur(5px); /* Blur effect for the background */
9+
border-radius: 15px;
10+
display: flex;
11+
align-items: center;
12+
padding: 2em;
13+
margin: 1em;
14+
gap: 1em;
15+
}

0 commit comments

Comments
 (0)