Skip to content

Commit 48fa42c

Browse files
authored
Merge branch 'main' into disable-rejoin-room-frontend
2 parents 9fc3096 + b2a0969 commit 48fa42c

File tree

6 files changed

+59
-33
lines changed

6 files changed

+59
-33
lines changed

backend/matching-service/controllers/roomController.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
import { AuthenticatedRequest } from "middlewares/auth";
12
import roomModel from "../models/RoomSchema";
2-
import { Request, Response, NextFunction } from "express";
3+
import { Response, NextFunction } from "express";
34

45
const ROOM_LIFESPAN = parseInt(process.env.ROOM_LIFESPAN || "86400000"); // 86400000ms = 1 day
56

67
export async function getRoomDetails(
7-
request: Request,
8+
request: AuthenticatedRequest,
89
response: Response,
910
next: NextFunction
1011
) {
@@ -13,11 +14,14 @@ export async function getRoomDetails(
1314
console.log(roomId)
1415
const room = await roomModel.findOne({ roomId });
1516
if (!room) {
16-
throw new Error("Room not found");
17+
throw new Error("Room not found.");
18+
}
19+
if (room.participants.every((participant) => participant !== request.userId)) {
20+
throw new Error("Non-matched user cannot enter this room.");
1721
}
1822
if (Date.now() - room.createdAt.getTime() > ROOM_LIFESPAN) {
19-
throw new Error("Room has expired");
20-
}
23+
throw new Error("Room has expired.");
24+
}
2125
response.status(200).json({
2226
roomId,
2327
attemptStartedAt: room.createdAt.getTime(),

backend/question-service/controllers/historyController.ts

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,20 @@ export const getUserHistoryEntries = async (req: any, res: Response) => {
1717
model: "category",
1818
},
1919
});
20-
const historyViewModels = historyEntries.map((entry) => {
20+
21+
historyEntries.forEach(async (entry) => {
22+
if (entry.question === null) {
23+
await historyEntryModel.findByIdAndDelete({_id: entry._id});
24+
}
25+
})
26+
27+
const historyViewModels = historyEntries
28+
.filter((entry) => !(entry.question === null))
29+
.map((entry) => {
2130
const attemptStartDate = new Date(entry.attemptStartedAt);
2231
const timeDiffMs = Date.now() - attemptStartDate.getTime();
23-
2432
const isWithin24Hours = timeDiffMs < 86400000; // 1 Day; Same as ROOM_LIFESPAN in MatchingService. Can be different if desired.
25-
33+
2634
return {
2735
id: entry._id,
2836
key: entry._id,
@@ -32,6 +40,7 @@ export const getUserHistoryEntries = async (req: any, res: Response) => {
3240
title: entry.question.title,
3341
difficulty: entry.question.difficulty,
3442
topics: entry.question.categories.map((cat: any) => cat.name),
43+
description: entry.question.description,
3544
attemptCodes: entry.attemptCodes.filter((attemptCode) => attemptCode && attemptCode !== ""),
3645
};
3746
});
@@ -90,26 +99,6 @@ export const createOrUpdateUserHistoryEntry = async (req: any, res: Response) =>
9099
}
91100
};
92101

93-
export const removeRoomIdPresence = async (req: any, res: Response) => {
94-
try {
95-
const userId = req.userId;
96-
const { roomId } = req.params;
97-
98-
const existingEntries = await historyEntryModel.find({ roomId });
99-
const updatedEntries: string[] = [];
100-
101-
existingEntries.forEach(async (entry) => {
102-
entry.roomId = "";
103-
await entry.save();
104-
updatedEntries.push(entry._id.toString());
105-
});
106-
107-
return res.status(200).json({ updatedEntries });
108-
} catch (error) {
109-
return res.status(500).json({ error: getErrorMessage(error) });
110-
}
111-
};
112-
113102
export const deleteUserHistoryEntry = async (req: any, res: Response) => {
114103
try {
115104
const userId = req.userId;

backend/question-service/controllers/questionsController.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Request, Response, NextFunction } from "express";
44
import { EachMessagePayload } from "kafkajs";
55
import { producer, QUESTION_TOPIC } from "../utils/kafkaClient";
66
import { Types } from "mongoose";
7+
import historyEntryModel from "../models/HistoryEntry";
78

89
const DIFFICULTIES = ["easy", "medium", "hard"];
910

@@ -143,6 +144,7 @@ export async function deleteQuestion(
143144
const { id } = request.params;
144145

145146
try {
147+
await historyEntryModel.deleteMany({ question: id });
146148
const deletedQuestion = await questionModel.findOneAndDelete({
147149
_id: id,
148150
});

backend/question-service/routes/historyRoutes.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@ import {
55
deleteUserHistoryEntry,
66
deleteUserHistoryEntries,
77
deleteAllUserHistoryEntries,
8-
removeRoomIdPresence,
98
} from "../controllers/historyController";
109
import { verifyAccessToken } from "../middlewares/basic-access-control";
1110

1211
const router = express.Router();
1312

1413
router.get("/", verifyAccessToken, getUserHistoryEntries);
1514
router.post("/", verifyAccessToken, createOrUpdateUserHistoryEntry);
16-
router.post("/room/:id", verifyAccessToken, removeRoomIdPresence);
1715
router.delete("/user/:id", verifyAccessToken, deleteUserHistoryEntry);
1816
router.delete("/user", verifyAccessToken, deleteUserHistoryEntries);
1917
router.delete("/all", verifyAccessToken, deleteAllUserHistoryEntries);

frontend/src/domain/entities/HistoryEntry.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ export interface HistoryEntry {
77
title: string;
88
difficulty: 'Easy' | 'Medium' | 'Hard';
99
topics: string[];
10+
description: string;
1011
attemptCodes: string[];
1112
}

frontend/src/presentation/components/RecentAttemptsTable.tsx

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { historyUseCases } from "domain/usecases/HistoryUseCases";
88
import { ReactMarkdown } from "./common/ReactMarkdown";
99
import TabPane from "antd/es/tabs/TabPane";
1010
import { useNavigate } from "react-router-dom";
11-
import { EyeOutlined, TeamOutlined } from "@ant-design/icons"; // Importing additional icons
11+
import { EyeOutlined, TeamOutlined } from "@ant-design/icons";
1212

1313
const formatDate = (dateString: string): string => {
1414
const options: Intl.DateTimeFormatOptions = {
@@ -42,7 +42,7 @@ const calculateDuration = (start: string, end: string): string => {
4242
};
4343

4444
export const RecentAttemptsTable: React.FC = () => {
45-
const navigate = useNavigate(); // Initialized navigate
45+
const navigate = useNavigate();
4646

4747
// State Definitions
4848
const [recentAttemptsData, setRecentAttemptsData] = useState<HistoryEntry[]>([]);
@@ -53,6 +53,10 @@ export const RecentAttemptsTable: React.FC = () => {
5353
const [isModalVisible, setIsModalVisible] = useState<boolean>(false);
5454
const [currentCodes, setCurrentCodes] = useState<string[]>([]);
5555

56+
// Modal State for Viewing Description
57+
const [isDescriptionModalVisible, setIsDescriptionModalVisible] = useState<boolean>(false);
58+
const [currentDescription, setCurrentDescription] = useState<string>('');
59+
5660
// Fetch Recent Attempts on Component Mount
5761
useEffect(() => {
5862
fetchRecentAttempts();
@@ -130,6 +134,18 @@ export const RecentAttemptsTable: React.FC = () => {
130134
setCurrentCodes([]);
131135
};
132136

137+
// Function to Show Description Modal
138+
const showDescriptionModal = (description: string) => {
139+
setCurrentDescription(description);
140+
setIsDescriptionModalVisible(true);
141+
};
142+
143+
// Function to Close Description Modal
144+
const handleDescriptionModalClose = () => {
145+
setIsDescriptionModalVisible(false);
146+
setCurrentDescription('');
147+
};
148+
133149
// Define Columns for the Table
134150
const columns: ColumnsType<HistoryEntry> = [
135151
{
@@ -169,7 +185,11 @@ export const RecentAttemptsTable: React.FC = () => {
169185
title: 'Title',
170186
dataIndex: 'title',
171187
key: 'title',
172-
render: (text: string) => <Typography.Text>{text}</Typography.Text>,
188+
render: (text: string, record: HistoryEntry) => (
189+
<Typography.Link onClick={() => showDescriptionModal(record.description)}>
190+
{text}
191+
</Typography.Link>
192+
),
173193
},
174194
{
175195
title: 'Difficulty',
@@ -308,6 +328,18 @@ export const RecentAttemptsTable: React.FC = () => {
308328
<Empty description="No code available" />
309329
)}
310330
</Modal>
331+
332+
<Modal
333+
title="Question Description"
334+
open={isDescriptionModalVisible}
335+
onCancel={handleDescriptionModalClose}
336+
footer={null}
337+
width={800}
338+
>
339+
<div style={{ height: '100%', overflow: 'auto', padding: '16px' }}>
340+
<ReactMarkdown isReadOnly value={currentDescription} />
341+
</div>
342+
</Modal>
311343
</div>
312344
);
313345
};

0 commit comments

Comments
 (0)