feat: add functionality to mark questions for review and update styles for marked questions
This commit is contained in:
@@ -19,6 +19,7 @@ const CodeChallenge = () => {
|
|||||||
const [terminalInput, setTerminalInput] = useState('');
|
const [terminalInput, setTerminalInput] = useState('');
|
||||||
const [waitingForInput, setWaitingForInput] = useState(false);
|
const [waitingForInput, setWaitingForInput] = useState(false);
|
||||||
const [activeTab, setActiveTab] = useState('console'); // 'console' or 'testcases'
|
const [activeTab, setActiveTab] = useState('console'); // 'console' or 'testcases'
|
||||||
|
const [markedForReview, setMarkedForReview] = useState({}); // Track questions marked for review
|
||||||
const socketRef = useRef(null);
|
const socketRef = useRef(null);
|
||||||
const terminalInputRef = useRef(null);
|
const terminalInputRef = useRef(null);
|
||||||
const { token } = useAuth();
|
const { token } = useAuth();
|
||||||
@@ -40,6 +41,17 @@ const CodeChallenge = () => {
|
|||||||
setLanguage(firstQuestion.programming_language || 'JavaScript');
|
setLanguage(firstQuestion.programming_language || 'JavaScript');
|
||||||
setCode(firstQuestion.code_template || getDefaultTemplate(firstQuestion.programming_language || 'JavaScript'));
|
setCode(firstQuestion.code_template || getDefaultTemplate(firstQuestion.programming_language || 'JavaScript'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load marked for review questions from localStorage
|
||||||
|
const markedKey = `marked_for_review_${parsedData.id}`;
|
||||||
|
const savedMarked = localStorage.getItem(markedKey);
|
||||||
|
if (savedMarked) {
|
||||||
|
try {
|
||||||
|
setMarkedForReview(JSON.parse(savedMarked));
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error loading marked questions:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error loading test data:', error);
|
console.error('Error loading test data:', error);
|
||||||
}
|
}
|
||||||
@@ -653,6 +665,40 @@ const CodeChallenge = () => {
|
|||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Handle mark for review
|
||||||
|
const handleMarkForReview = () => {
|
||||||
|
if (!test) return;
|
||||||
|
|
||||||
|
const currentIndex = getQuestionIndex(activeQuestion);
|
||||||
|
const currentQuestion = getCurrentQuestion();
|
||||||
|
if (!currentQuestion) return;
|
||||||
|
|
||||||
|
const questionId = currentQuestion.id;
|
||||||
|
const isCurrentlyMarked = markedForReview[questionId];
|
||||||
|
|
||||||
|
// Toggle marked status
|
||||||
|
const updatedMarked = {
|
||||||
|
...markedForReview,
|
||||||
|
[questionId]: !isCurrentlyMarked
|
||||||
|
};
|
||||||
|
|
||||||
|
setMarkedForReview(updatedMarked);
|
||||||
|
|
||||||
|
// Save to localStorage
|
||||||
|
const markedKey = `marked_for_review_${test.id}`;
|
||||||
|
localStorage.setItem(markedKey, JSON.stringify(updatedMarked));
|
||||||
|
|
||||||
|
// Show feedback
|
||||||
|
setTerminalOutput([
|
||||||
|
{
|
||||||
|
type: 'system',
|
||||||
|
content: !isCurrentlyMarked
|
||||||
|
? `✓ Question ${currentIndex + 1} marked for review`
|
||||||
|
: `✓ Question ${currentIndex + 1} unmarked for review`
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
// Handle final test submission
|
// Handle final test submission
|
||||||
const handleSubmitTest = async () => {
|
const handleSubmitTest = async () => {
|
||||||
if (!test) {
|
if (!test) {
|
||||||
@@ -827,10 +873,13 @@ const CodeChallenge = () => {
|
|||||||
{(questions.length > 0 ? questions : Array.from({length: 20}, (_, i) => i + 1)).map((q, idx) => {
|
{(questions.length > 0 ? questions : Array.from({length: 20}, (_, i) => i + 1)).map((q, idx) => {
|
||||||
const questionKey = `Q.${idx + 1}`;
|
const questionKey = `Q.${idx + 1}`;
|
||||||
const questionNum = idx + 1;
|
const questionNum = idx + 1;
|
||||||
|
const question = questions[idx];
|
||||||
|
const isMarked = question && markedForReview[question.id];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
key={questionKey}
|
key={questionKey}
|
||||||
className={`question-palette-btn ${activeQuestion === questionKey ? "palette-active" : ""}`}
|
className={`question-palette-btn ${activeQuestion === questionKey ? "palette-active" : ""} ${isMarked ? "palette-marked" : ""}`}
|
||||||
onClick={() => setActiveQuestion(questionKey)}
|
onClick={() => setActiveQuestion(questionKey)}
|
||||||
disabled={questions.length > 0 && idx >= questions.length}
|
disabled={questions.length > 0 && idx >= questions.length}
|
||||||
>
|
>
|
||||||
@@ -1039,6 +1088,24 @@ const CodeChallenge = () => {
|
|||||||
|
|
||||||
{/* Action Buttons at Bottom Right */}
|
{/* Action Buttons at Bottom Right */}
|
||||||
<div className="action-bar">
|
<div className="action-bar">
|
||||||
|
<button
|
||||||
|
className="action-bar-btn action-mark"
|
||||||
|
onClick={handleMarkForReview}
|
||||||
|
disabled={!getCurrentQuestion()}
|
||||||
|
>
|
||||||
|
{(() => {
|
||||||
|
const currentQuestion = getCurrentQuestion();
|
||||||
|
const isMarked = currentQuestion && markedForReview[currentQuestion.id];
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<svg width="16" height="16" viewBox="0 0 24 24" fill={isMarked ? "currentColor" : "none"} stroke="currentColor" strokeWidth="2">
|
||||||
|
<path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/>
|
||||||
|
</svg>
|
||||||
|
{isMarked ? 'Unmark Review' : 'Mark for Review'}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
})()}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
className="action-bar-btn action-run"
|
className="action-bar-btn action-run"
|
||||||
onClick={runCode}
|
onClick={runCode}
|
||||||
|
|||||||
@@ -1311,6 +1311,18 @@ body {
|
|||||||
border-color: #007bff;
|
border-color: #007bff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.question-palette-btn.palette-marked {
|
||||||
|
background-color: #ff9800;
|
||||||
|
color: #ffffff;
|
||||||
|
border-color: #ff9800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-palette-btn.palette-active.palette-marked {
|
||||||
|
background-color: #ff6d00;
|
||||||
|
color: #ffffff;
|
||||||
|
border-color: #ff6d00;
|
||||||
|
}
|
||||||
|
|
||||||
.question-palette-btn:disabled {
|
.question-palette-btn:disabled {
|
||||||
opacity: 0.3;
|
opacity: 0.3;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
|
|||||||
Reference in New Issue
Block a user