From 58d045fcc55d8ce8e71418f5971da83591dbcfc5 Mon Sep 17 00:00:00 2001 From: Guan Quan <76832850+guanquann@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:25:00 +0800 Subject: [PATCH] Update question history with current progress when user end session without submitting previously --- .../CollabSessionControls/index.tsx | 16 +----- frontend/src/contexts/CollabContext.tsx | 52 ++++++++++++++++--- frontend/src/pages/CollabSandbox/index.tsx | 5 +- 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/frontend/src/components/CollabSessionControls/index.tsx b/frontend/src/components/CollabSessionControls/index.tsx index a35599d7a8..81b30bdb6a 100644 --- a/frontend/src/components/CollabSessionControls/index.tsx +++ b/frontend/src/components/CollabSessionControls/index.tsx @@ -2,26 +2,14 @@ import { Button, Stack } from "@mui/material"; import Stopwatch from "../Stopwatch"; import { useCollab } from "../../contexts/CollabContext"; import { USE_COLLAB_ERROR_MESSAGE } from "../../utils/constants"; -import { useEffect, useState } from "react"; const CollabSessionControls: React.FC = () => { - const [time, setTime] = useState(0); - - useEffect(() => { - const intervalId = setInterval( - () => setTime((prevTime) => prevTime + 1), - 1000 - ); - - return () => clearInterval(intervalId); - }, [time]); - const collab = useCollab(); if (!collab) { throw new Error(USE_COLLAB_ERROR_MESSAGE); } - const { handleSubmitSessionClick, handleEndSessionClick } = collab; + const { handleSubmitSessionClick, handleEndSessionClick, time } = collab; return ( @@ -33,7 +21,7 @@ const CollabSessionControls: React.FC = () => { }} variant="outlined" color="success" - onClick={() => handleSubmitSessionClick(time)} + onClick={() => handleSubmitSessionClick()} > Submit diff --git a/frontend/src/contexts/CollabContext.tsx b/frontend/src/contexts/CollabContext.tsx index 7d81ed2d03..372b127338 100644 --- a/frontend/src/contexts/CollabContext.tsx +++ b/frontend/src/contexts/CollabContext.tsx @@ -1,6 +1,6 @@ /* eslint-disable react-refresh/only-export-components */ -import React, { createContext, useContext, useState } from "react"; +import React, { createContext, useContext, useEffect, useState } from "react"; import { USE_MATCH_ERROR_MESSAGE, FAILED_TESTCASE_MESSAGE, @@ -11,7 +11,7 @@ import { import { toast } from "react-toastify"; import { useMatch } from "./MatchContext"; -import { codeExecutionClient } from "../utils/api"; +import { qnHistoryClient, codeExecutionClient } from "../utils/api"; import { useReducer } from "react"; import { updateQnHistoryById } from "../reducers/qnHistoryReducer"; import qnHistoryReducer, { initialQHState } from "../reducers/qnHistoryReducer"; @@ -33,15 +33,16 @@ export type CompilerResult = { }; type CollabContextType = { - handleSubmitSessionClick: (time: number) => void; + handleSubmitSessionClick: () => void; handleEndSessionClick: () => void; handleRejectEndSession: () => void; handleConfirmEndSession: () => void; checkPartnerStatus: () => void; setCode: React.Dispatch>; compilerResult: CompilerResult[]; - setCompilerResult: React.Dispatch>; isEndSessionModalOpen: boolean; + time: number; + resetCollab: () => void; }; const CollabContext = createContext(null); @@ -66,6 +67,17 @@ const CollabProvider: React.FC<{ children?: React.ReactNode }> = (props) => { qnHistoryId, } = match; + const [time, setTime] = useState(0); + + useEffect(() => { + const intervalId = setInterval( + () => setTime((prevTime) => prevTime + 1), + 1000 + ); + + return () => clearInterval(intervalId); + }, [time]); + // eslint-disable-next-line const [_qnHistoryState, qnHistoryDispatch] = useReducer( qnHistoryReducer, @@ -76,7 +88,7 @@ const CollabProvider: React.FC<{ children?: React.ReactNode }> = (props) => { const [isEndSessionModalOpen, setIsEndSessionModalOpen] = useState(false); - const handleSubmitSessionClick = async (time: number) => { + const handleSubmitSessionClick = async () => { try { const res = await codeExecutionClient.post("/", { questionId, @@ -124,9 +136,26 @@ const CollabProvider: React.FC<{ children?: React.ReactNode }> = (props) => { setIsEndSessionModalOpen(false); }; - const handleConfirmEndSession = () => { + const handleConfirmEndSession = async () => { setIsEndSessionModalOpen(false); + // Get queston history + const data = await qnHistoryClient.get(qnHistoryId as string); + + // Only update question history if it has not been submitted before + if (!data.data.qnHistory.code) { + updateQnHistoryById( + qnHistoryId as string, + { + submissionStatus: "Attempted", + dateAttempted: new Date().toISOString(), + timeTaken: time, + code: code.replace(/\t/g, " ".repeat(4)), + }, + qnHistoryDispatch + ); + } + // Leave collaboration room leave(matchUser?.id as string, getMatchId() as string, true); leave(partner?.id as string, getMatchId() as string, true); @@ -137,6 +166,9 @@ const CollabProvider: React.FC<{ children?: React.ReactNode }> = (props) => { // Delete match data stopMatch(); appNavigate("/home"); + + // Reset collab state + resetCollab(); }; const checkPartnerStatus = () => { @@ -148,6 +180,11 @@ const CollabProvider: React.FC<{ children?: React.ReactNode }> = (props) => { }); }; + const resetCollab = () => { + setCompilerResult([]); + setTime(0); + }; + return ( = (props) => { checkPartnerStatus, setCode, compilerResult, - setCompilerResult, isEndSessionModalOpen, + time, + resetCollab, }} > {children} diff --git a/frontend/src/pages/CollabSandbox/index.tsx b/frontend/src/pages/CollabSandbox/index.tsx index 5c27452f42..cadaa8095c 100644 --- a/frontend/src/pages/CollabSandbox/index.tsx +++ b/frontend/src/pages/CollabSandbox/index.tsx @@ -62,11 +62,11 @@ const CollabSandbox: React.FC = () => { const { compilerResult, - setCompilerResult, handleRejectEndSession, handleConfirmEndSession, checkPartnerStatus, isEndSessionModalOpen, + resetCollab, } = collab; const [state, dispatch] = useReducer(reducer, initialState); @@ -81,7 +81,8 @@ const CollabSandbox: React.FC = () => { return; } getQuestionById(questionId, dispatch); - setCompilerResult([]); + + resetCollab(); const matchId = getMatchId(); if (!matchUser || !matchId) {