Skip to content

Commit 837cac0

Browse files
authored
Merge pull request #47 from Pedram-Karimi/adminPage
admin page
2 parents 0880fd5 + 9087d33 commit 837cac0

15 files changed

Lines changed: 562 additions & 145 deletions

File tree

React-Component/src/pages/home/home.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
display: flex;
1818
gap: 2em;
1919
margin-bottom: 50px;
20+
background-color: blue;
2021
}
2122

2223
.info {
@@ -316,4 +317,4 @@ footer {
316317

317318
.buy-now:hover img {
318319
filter: brightness(0.9);
319-
}
320+
}

React-Component/src/pages/home/home.jsx

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,31 +39,25 @@ const Home = () => {
3939
Helping your child develop <br />
4040
critical thinking skills!
4141
</h1>
42-
4342
<p>
44-
We are a nonprofit organization empowering <br></br>children to find
45-
their own success in STEM through <br></br>Chess, Math and Computer
46-
Science.
43+
We are a nonprofit organization empowering <br />
44+
children to find their own success in STEM through <br />
45+
Chess, Math and Computer Science.
4746
</p>
4847

4948
<button className="donate-button" onClick={handleDonateButton}>
5049
<strong>Donate</strong>
5150
</button>
5251
</div>
53-
<div className="pic">
54-
<img
55-
src={Images.TreesGroup}
56-
id="tree-group-img"
57-
alt="ystemandchess mascot"
58-
></img>
59-
</div>
52+
53+
<img
54+
src={Images.TreesGroup}
55+
id="tree-group-img"
56+
alt="ystemandchess mascot"
57+
/>
6058
</div>
6159

62-
<img
63-
src={Images.LogoLineBr}
64-
className="logo-break"
65-
alt="line break"
66-
></img>
60+
<img src={Images.LogoLineBr} className="logo-break" alt="line break" />
6761

6862
<h1 id="floating-h1">Everyone is included.</h1>
6963
<h1 id="floating-h1">Everyone is welcomed.</h1>
@@ -160,4 +154,4 @@ const Home = () => {
160154
);
161155
};
162156

163-
export default Home;
157+
export default Home;
Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
1-
import React, {useState} from "react";
1+
import React, { useState } from "react";
22
import "./Student.scss";
33
import {environment} from "../../environments/environment.js";
44

55
const Student = () => {
6-
const chessSrc = environment.urls.chessClientURL;
7-
const [movesAhead, setMovesAhead] = useState(5);
6+
const chessSrc = environment.urls.chessClientURL;
7+
const [movesAhead, setMovesAhead] = useState(5);
88

9-
return (
10-
<div className="chess-body">
11-
<br />
12-
<br />
13-
<br />
14-
<iframe src={chessSrc} title="Chessboard" height="500" width="500"/>
15-
<br />
16-
<br />
17-
<br />
18-
<button>New Game</button>
19-
<button>Play with a computer</button>
20-
<button>Undo</button>
21-
<br />
22-
<p>
23-
The computer will think
24-
<input type="number" min="1" step="1" max="30" value={movesAhead}/>
25-
moves ahead of you
26-
</p>
27-
<br />
28-
</div>
29-
)
30-
}
9+
return (
10+
<div className="chess-body">
11+
<br />
12+
<br />
13+
<br />
14+
<iframe src={chessSrc} title="Chessboard" height="500" width="500" />
15+
<br />
16+
<br />
17+
<br />
18+
<button>New Game</button>
19+
<button>Play with a computer</button>
20+
<button>Undo</button>
21+
<br />
22+
<p>
23+
The computer will think
24+
<input type="number" min="1" step="1" max="30" value={movesAhead} />
25+
moves ahead of you
26+
</p>
27+
<br />
28+
</div>
29+
);
30+
};
3131

3232
export default Student;

middlewareNode/src/routes/users.js

Lines changed: 97 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const express = require("express");
1717
const passport = require("passport");
1818
const router = express.Router();
1919
const crypto = require("crypto");
20+
const jwt = require("jsonwebtoken");
2021
const { check, validationResult } = require("express-validator");
2122
const users = require("../models/users");
2223
const Activities = require("../models/activities");
@@ -26,7 +27,7 @@ const {
2627
} = require("../template/changePasswordTemplate");
2728
const { sendMail } = require("../utils/nodemailer");
2829
const { validator } = require("../utils/middleware");
29-
const { MongoClient } = require('mongodb');
30+
const { MongoClient } = require("mongodb");
3031
const config = require("config");
3132

3233
// Cache database client to prevent repeated connections
@@ -110,7 +111,6 @@ router.post(
110111
//Set the account created date for the new user
111112
const currDate = new Date();
112113

113-
114114
//Switch statement for functionality depending on role
115115
if (role === "parent") {
116116
let studentsArray = JSON.parse(students);
@@ -180,7 +180,7 @@ router.post(
180180
console.error(error.message);
181181
res.status(500).json("Server error");
182182
}
183-
},
183+
}
184184
);
185185

186186
// @route POST /user/children
@@ -236,7 +236,7 @@ router.post(
236236
console.error(error.message);
237237
res.status(500).json("Server error");
238238
}
239-
},
239+
}
240240
);
241241
// @route POST /user/sendMail
242242
// @desc sending the mail based on username and email
@@ -289,15 +289,15 @@ const updatePassword = async (body) => {
289289
const result = await users.findOneAndUpdate(
290290
{ username: body.username, email: body.email },
291291
{ password: body.password },
292-
{ new: true },
292+
{ new: true }
293293
);
294294
return result;
295295
};
296296

297297
// @route GET /user/mentorless/:keyword
298298
// @desc for getting the mentorless students whose username matches keyword.
299299
router.get("/mentorless", async (req, res) => {
300-
const keyword = req.query.keyword || ''; // get the keyword
300+
const keyword = req.query.keyword || ""; // get the keyword
301301
try {
302302
const db = await getDb();
303303
const users = db.collection("users");
@@ -318,21 +318,28 @@ router.get("/mentorless", async (req, res) => {
318318
// @desc if user is mentor, update its student username to the mentorship= query
319319
// @access Public with jwt Authentication
320320
router.put(
321-
"/updateMentorship",
321+
"/updateMentorship",
322322
async (req, res, next) => {
323-
passport.authenticate("jwt", { session: false }, async (err, user, info) => {
324-
if (!user) {
325-
return res.status(401).json({ message: "Unauthorized" });
323+
passport.authenticate(
324+
"jwt",
325+
{ session: false },
326+
async (err, user, info) => {
327+
if (!user) {
328+
return res.status(401).json({ message: "Unauthorized" });
329+
}
330+
req.user = user;
331+
next();
326332
}
327-
req.user = user;
328-
next();
329-
})(req, res, next) // authenticate jwt
330-
},
333+
)(req, res, next); // authenticate jwt
334+
},
331335
async (req, res) => {
332336
// get the student/mentor username
333337
const mentorship = req.query.mentorship;
334-
if (!mentorship) { // mentorship query is required
335-
return res.status(400).json({ message: "Missing mentorship username in query" });
338+
if (!mentorship) {
339+
// mentorship query is required
340+
return res
341+
.status(400)
342+
.json({ message: "Missing mentorship username in query" });
336343
}
337344

338345
try {
@@ -359,23 +366,28 @@ router.put(
359366
} catch (err) {
360367
res.status(500).json({ error: err.message }); // error
361368
}
362-
}
369+
}
363370
);
364371

365372
// @route GET /user/getMentorship
366373
// @desc if user is a student, responds with its mentor's object {username, firstName, lastName}
367374
// @desc if user is a mentor, responds with its student's object {username, firstName, lastName}
368375
// @access Public with jwt Authentication
369-
router.get("/getMentorship",
376+
router.get(
377+
"/getMentorship",
370378
async (req, res, next) => {
371-
passport.authenticate("jwt", { session: false }, async (err, user, info) => {
372-
if (!user) {
373-
return res.status(401).json({ message: "Unauthorized" });
379+
passport.authenticate(
380+
"jwt",
381+
{ session: false },
382+
async (err, user, info) => {
383+
if (!user) {
384+
return res.status(401).json({ message: "Unauthorized" });
385+
}
386+
req.user = user;
387+
next();
374388
}
375-
req.user = user;
376-
next();
377-
})(req, res, next) // authenticate jwt
378-
},
389+
)(req, res, next); // authenticate jwt
390+
},
379391
async (req, res) => {
380392
try {
381393
const db = await getDb();
@@ -402,4 +414,63 @@ router.get("/getMentorship",
402414
}
403415
);
404416

405-
module.exports = router;
417+
router.get("/getStudent", async (req, res) => {
418+
const keyword = req.query.keyword || "";
419+
420+
try {
421+
const db = await getDb();
422+
const users = db.collection("users");
423+
424+
const userList = await users
425+
.find({
426+
role: "student", // get student
427+
username: { $regex: keyword, $options: "i" }, // case-insensitive match for username
428+
})
429+
.toArray();
430+
431+
res.json(userList.map((user) => user.username)); // return a list of the usernames
432+
} catch (err) {
433+
res.status(500).json({ error: err.message }); // error
434+
}
435+
});
436+
437+
// verify role
438+
439+
router.post("/verifyRole", async (req, res) => {
440+
const { token } = req.body;
441+
442+
if (!token.login) {
443+
return res.status(400).json({ error: "Missing token" });
444+
}
445+
446+
const decoded = jwt.verify(token.login, config.get("indexKey"));
447+
448+
const user = await users
449+
.findOne({ username: decoded.username })
450+
.select("role");
451+
452+
if (!user) {
453+
return res.status(404).json({ error: "User not found" });
454+
}
455+
console.log(decoded.role, user.role);
456+
if (decoded.role === user.role) {
457+
return res.json({ verified: true });
458+
} else {
459+
return res.status(403).json({ error: "Role mismatch", verified: false });
460+
}
461+
});
462+
463+
router.get("/getUser", async (req, res) => {
464+
const username = req.query.username || "";
465+
try {
466+
const user = await users.findOne({ username }).select("-password");
467+
if (!user) {
468+
return res.status(404).json({ error: "User not found" });
469+
}
470+
return res.status(200).json(user);
471+
} catch (err) {
472+
return res.status(401).json({ error: err });
473+
}
474+
});
475+
476+
module.exports = router;

react-ystemandchess/jest.config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module.exports = {
22
transform: {
3-
'^.+\\.(ts|tsx|js|jsx)$': 'babel-jest',
3+
"^.+\\.(ts|tsx|js|jsx)$": "babel-jest",
44
},
55
moduleNameMapper: {
66
'\\.(css|scss|sass)$': 'identity-obj-proxy',
@@ -13,4 +13,4 @@ module.exports = {
1313
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
1414
setupFilesAfterEnv: ['@testing-library/jest-dom'],
1515
moduleDirectories: ['node_modules', 'src'],
16-
};
16+
};

react-ystemandchess/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,4 @@
9898
"volta": {
9999
"node": "18.20.8"
100100
}
101-
}
101+
}

react-ystemandchess/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,4 @@ function App() {
159159
);
160160
}
161161

162-
export default App;
162+
export default App;

0 commit comments

Comments
 (0)