Skip to content

Commit 509911f

Browse files
committed
2 parents b4374bc + 2065ec3 commit 509911f

File tree

15 files changed

+193
-81
lines changed

15 files changed

+193
-81
lines changed

MatchingService/src/matching/matching.service.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export function initializeMatchingService(io: Server) {
1212
socket.on('startMatching', (preferences: any) => {
1313
// Add the user to the list of active users with their preferences
1414
activeUsers.push({ socket, preferences });
15+
//console.log('user is in queue to match with another user');
1516

1617
// Attempt to find a match for the user
1718
tryMatchForUser(socket, preferences);
@@ -61,6 +62,7 @@ export function initializeMatchingService(io: Server) {
6162
removeUserFromActiveList(matchedUser.socket);
6263
const randomSeed = Date.now();
6364
// Emit "matchFound" to both users
65+
//console.log('match found');
6466
socket.emit('matchFound', {matchedUserPreferences: matchedUser.preferences, seed: randomSeed});
6567
matchedUser.socket.emit('matchFound', {matchedUserPreferences: preferences, seed: randomSeed});
6668
} else {

frontend/src/auth/AdminAuthGuard.tsx renamed to frontend/src/auth/AdminGuard.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ interface AuthGuardProps {
66
children: ReactNode;
77
}
88

9-
export default function AdminAuthGuard({ children }: AuthGuardProps) {
9+
export default function AdminGuard({ children }: AuthGuardProps) {
1010
const { user } = useAuth();
11-
if (user?.role !== "admin") {
12-
return <Navigate to="/home" />;
11+
if (user?.role !== "admin" && user?.role !== "master") {
12+
return <Navigate to="/login" />;
1313
}
1414
return <>{children}</>;
1515
}

frontend/src/auth/MaintainerGuard.tsx renamed to frontend/src/auth/MasterGuard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ interface AuthGuardProps {
66
children: ReactNode;
77
}
88

9-
export default function MaintainerGuard({ children }: AuthGuardProps) {
9+
export default function MasterGuard({ children }: AuthGuardProps) {
1010
const { user } = useAuth();
11-
if (user?.role !== "maintainer") {
11+
if (user?.role !== "master") {
1212
return <Navigate to="/login" />;
1313
}
1414
return <>{children}</>;

frontend/src/components/CollabProblemSolverLeft.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ function CollabProblemSolverLeft({
4545
</Typography>
4646
<Divider sx={{ marginBottom: 2, marginTop: 5 }} />
4747
<Typography variant="body1" sx={{ marginBottom: 2, fontSize: "18px" }}>
48-
{question.description}
48+
{question.description.split("\\n").map((s, key) => {
49+
return <p key={key}>{s}</p>;
50+
})}
4951
</Typography>
5052
<Divider sx={{ marginBottom: 10 }} />
5153
<Typography variant="h6" gutterBottom sx={{ fontSize: "18px" }}>

frontend/src/components/MatchingService/MatchingForm.tsx

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,21 @@ const MatchingForm = React.forwardRef(function MatchingForm() {
6262
const userEmail = user?.email;
6363
const [openSnackbar, setOpenSnackbar] = React.useState(false);
6464
const [snackbarMessage, setSnackbarMessage] = React.useState("");
65+
const [remainingTime, setRemainingTime] = React.useState(0); // State for the countdown timer
66+
const [timerId, setTimerId] = React.useState<NodeJS.Timeout | null>(null); // State to keep track of the timer
67+
68+
69+
const startCountdown = () => {
70+
setRemainingTime(30); // Start the timer at 30 seconds
71+
setIsMatching(true);
72+
// Clear any existing timer
73+
if (timerId) clearInterval(timerId);
74+
// Start a new timer
75+
const id = setInterval(() => {
76+
setRemainingTime((time) => time - 1);
77+
}, 1000);
78+
setTimerId(id);
79+
};
6580

6681
React.useEffect(() => {
6782
getQuestions();
@@ -91,8 +106,24 @@ const MatchingForm = React.forwardRef(function MatchingForm() {
91106

92107
socket.emit("startMatching", preferences);
93108
setIsMatching(true);
109+
startCountdown();
94110
};
95111

112+
React.useEffect(() => {
113+
if (remainingTime === 0 && timerId) {
114+
clearInterval(timerId);
115+
setIsMatching(false); // Update isMatching state to false as matching ends
116+
setSnackbarMessage("Matching timed out after 30 seconds.");
117+
setOpenSnackbar(true);
118+
}
119+
}, [remainingTime, timerId]);
120+
121+
React.useEffect(() => {
122+
return () => {
123+
if (timerId) clearInterval(timerId);
124+
};
125+
}, [timerId]);
126+
96127
const generateConsistentRandomIndex = (seed: any, arrayLength: number) => {
97128
return seed % arrayLength;
98129
};
@@ -130,6 +161,8 @@ const MatchingForm = React.forwardRef(function MatchingForm() {
130161
// eslint-disable-next-line
131162
}, [questions]);
132163

164+
165+
133166
React.useEffect(() => {
134167
socket.on("matchFound", async (matchedUserPreferences) => {
135168
console.log("Match Found:", matchedUserPreferences);
@@ -210,7 +243,10 @@ const MatchingForm = React.forwardRef(function MatchingForm() {
210243
</select>
211244
</div>
212245
{isMatching ? (
213-
<div>Loading...</div>
246+
<div>Loading...
247+
<p>Time remaining: {remainingTime} seconds</p>
248+
</div>
249+
214250
) : (
215251
<Button sx={{ mt: "5%" }} variant="contained" onClick={handleConnect}>
216252
Connect
@@ -236,4 +272,4 @@ const MatchingForm = React.forwardRef(function MatchingForm() {
236272
);
237273
});
238274

239-
export default MatchingForm;
275+
export default MatchingForm;

frontend/src/components/Navbar.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export default function Navbar() {
6868
{ name: "Dashboard", onclick: handleCloseUserMenu },
6969
{ name: "Logout", onclick: logout },
7070
];
71-
if (user?.role === "maintainer") {
71+
if (user?.role === "master") {
7272
settings = settings.concat({
7373
name: "Create Admin",
7474
onclick: () => navigate("/createadmin", { replace: true }),
@@ -133,7 +133,7 @@ export default function Navbar() {
133133
<Typography textAlign="center">{page.name}</Typography>
134134
</MenuItem>
135135
))}
136-
{user?.role === "admin" &&
136+
{(user?.role === "admin" || user?.role === "master") &&
137137
adminPages.map((page) => (
138138
<MenuItem key={page.name} onClick={() => navigate(page.link)}>
139139
<Typography textAlign="center">{page.name}</Typography>
@@ -177,7 +177,7 @@ export default function Navbar() {
177177
{page.name}
178178
</Button>
179179
))}
180-
{user?.role === "admin" &&
180+
{(user?.role === "admin" || user?.role === "master") &&
181181
adminPages.map((page) => (
182182
<Button
183183
key={page.name}

frontend/src/components/ProblemSolverLeft.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// ProblemSolverLeft.jsx
2-
import React, {useEffect } from 'react';
2+
import React, { useEffect } from 'react';
33
import { useParams } from 'react-router-dom';
44
import {
55
Paper,
@@ -31,22 +31,24 @@ const ProblemSolverLeft = () => {
3131
// If the question is not found, display a message
3232
return (
3333
<Paper elevation={3} sx={{ flex: 1, display: 'flex', flexDirection: 'column', padding: 2 }}>
34-
<Typography variant="h4" gutterBottom>
35-
Question not found
36-
{questionId}
37-
</Typography>
38-
</Paper>
39-
);
40-
}
34+
<Typography variant="h4" gutterBottom>
35+
Question not found
36+
{questionId}
37+
</Typography>
38+
</Paper>
39+
);
40+
}
4141

4242
return (
43-
<Paper elevation={3} sx={{ flex: 1, display: 'flex', flexDirection: 'column', padding: 2 }}>
43+
<Paper elevation={3} sx={{ flex: 1, display: 'flex', flexDirection: 'column', padding: 2}}>
4444
<Typography variant="h4" gutterBottom sx={{ fontSize: '24px' }}>
4545
{question.title}
4646
</Typography>
4747
<Divider sx={{ marginBottom: 2, marginTop: 5 }} />
4848
<Typography variant="body1" sx={{ marginBottom: 2, fontSize: '18px' }}>
49-
{question.description}
49+
{question.description.split("\\n").map((s, key) => {
50+
return <p key={key}>{s}</p>;
51+
})}
5052
</Typography>
5153
<Divider sx={{ marginBottom: 10 }} />
5254
<Typography variant="h6" gutterBottom sx={{ fontSize: '18px' }}>
@@ -61,7 +63,7 @@ const ProblemSolverLeft = () => {
6163
<CardMedia
6264
component="img"
6365
alt={`Example ${index + 1}`}
64-
sx={{maxHeight: '100%', width: 'auto' }}
66+
sx={{ maxHeight: '100%', width: 'auto' }}
6567
height="140"
6668
image={example.image}
6769
/>

frontend/src/components/ProblemSolverRight.tsx

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
1-
import React, { useState } from 'react';
2-
import { Paper, Typography, TextField, MenuItem, Button } from '@mui/material';
1+
import React, { useState } from "react";
2+
import { Paper, Typography, TextField, MenuItem, Button } from "@mui/material";
3+
import { Link } from "react-router-dom";
4+
35
import Editor from "@monaco-editor/react";
46

5-
const languages: string[] = ['C++', 'Java', 'JavaScript', 'Python'];
7+
const languages: string[] = ["C++", "Java", "JavaScript", "Python"];
68

79
function ProblemSolverRight() {
8-
const [selectedLanguage, setSelectedLanguage] = useState<string>('JavaScript');
10+
const [selectedLanguage, setSelectedLanguage] =
11+
useState<string>("JavaScript");
912
// const [code, setCode] = useState<string>('class Solution:');
10-
const code = "class Solution:"
11-
const handleLanguageChange = (event: React.ChangeEvent<{ value: unknown }>) => {
13+
const code = "class Solution:";
14+
const handleLanguageChange = (
15+
event: React.ChangeEvent<{ value: unknown }>
16+
) => {
1217
setSelectedLanguage(event.target.value as string);
1318
};
1419

@@ -22,7 +27,10 @@ function ProblemSolverRight() {
2227
};
2328

2429
return (
25-
<Paper elevation={3} style={{ flex: 1, padding: 16, display: 'flex', flexDirection: 'column' }}>
30+
<Paper
31+
elevation={3}
32+
style={{ flex: 1, padding: 16, display: "flex", flexDirection: "column" }}
33+
>
2634
<Typography variant="h6" gutterBottom>
2735
Select a Language:
2836
</Typography>
@@ -31,33 +39,34 @@ function ProblemSolverRight() {
3139
fullWidth
3240
value={selectedLanguage}
3341
onChange={handleLanguageChange}
34-
style={{ width: '50%' }}
42+
style={{ width: "50%" }}
3543
>
3644
{languages.map((language, index) => (
3745
<MenuItem key={index} value={language}>
3846
{language}
3947
</MenuItem>
4048
))}
4149
</TextField>
42-
<Typography variant="h6" gutterBottom style={{ marginTop: '16px' }}>
50+
<Typography variant="h6" gutterBottom style={{ marginTop: "16px" }}>
4351
Code Editor:
4452
</Typography>
4553
<Editor
46-
height="900px"
47-
language={selectedLanguage.toLowerCase()}
48-
theme="vs-dark"
49-
value={code}
50-
51-
/>
52-
<Button
53-
variant="contained"
54-
color="primary"
55-
fullWidth
56-
onClick={handleSubmit}
57-
style={{ marginTop: '16px' }}
58-
>
59-
Submit
60-
</Button>
54+
height="900px"
55+
language={selectedLanguage.toLowerCase()}
56+
theme="vs-dark"
57+
value={code}
58+
/>
59+
<Link to={`/home`} style={{ textDecoration: "none" }}>
60+
<Button
61+
variant="contained"
62+
color="primary"
63+
fullWidth
64+
onClick={handleSubmit}
65+
style={{ marginTop: "16px" }}
66+
>
67+
Submit
68+
</Button>
69+
</Link>
6170
</Paper>
6271
);
6372
}

frontend/src/components/Questions/AddQuestionTab.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, { useState } from "react";
22
import QuestionForm from "./QuestionForm";
33
import { Box, Button } from "@mui/material";
44
import Question from "./Question";
@@ -7,7 +7,7 @@ import { addQuestion } from "../../api/questions/data";
77
import { AxiosError } from "axios";
88

99
const AddQuestionTab: React.FC = () => {
10-
const [addQuestions, setAddQuestions] = React.useState(false);
10+
const [addQuestions, setAddQuestions] = useState(false);
1111

1212
const handleAddQuestionClick = () => {
1313
setAddQuestions(true);
@@ -20,6 +20,9 @@ const AddQuestionTab: React.FC = () => {
2020
const questionAdded = await addQuestion(questionToAdd);
2121
console.log(questionAdded);
2222
setAddQuestions(false);
23+
24+
// Navigate to the current location to refresh the page
25+
window.location.reload();
2326
} catch (e) {
2427
if (e instanceof AxiosError && e.response) {
2528
console.log(e.response.data.code);

frontend/src/components/Questions/EditQuestionsTab.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const EditQuestionsTab: React.FC = () => {
2626
`Question ${editedQuestion.id} updated: ${editedQuestion.title}`
2727
);
2828
setEditQuestions(false);
29+
window.location.reload();
2930
} catch (e) {
3031
if (e instanceof AxiosError && e.response) {
3132
console.log(e.response.data.code);
@@ -34,7 +35,6 @@ const EditQuestionsTab: React.FC = () => {
3435
}
3536
}
3637
};
37-
3838
const onDelete = async (questionToDelete: Question) => {
3939
console.log("Question to Delete: ", questionToDelete);
4040

@@ -44,6 +44,7 @@ const EditQuestionsTab: React.FC = () => {
4444
`Question ${questionToDelete.id} deleted: ${questionToDelete.title}`
4545
);
4646
setEditQuestions(false);
47+
window.location.reload();
4748
} catch (e) {
4849
if (e instanceof AxiosError && e.response) {
4950
console.log(e.response.data.code);

0 commit comments

Comments
 (0)