Skip to content

Commit

Permalink
Merge pull request #48 from CS3219-AY2425S1/branch-N2H-CodeFormatting
Browse files Browse the repository at this point in the history
N2H N4 (Code Execution) and N5 (Enhanced Collab Service)
  • Loading branch information
bhnuka authored Nov 3, 2024
2 parents 44bba38 + 2e74c20 commit c25d200
Show file tree
Hide file tree
Showing 2 changed files with 204 additions and 39 deletions.
102 changes: 99 additions & 3 deletions peerprep/frontend/src/styles/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
margin: 0 auto;
padding: 5rem;
text-align: center;
background-color: white;
}

/* Global Styling */
Expand Down Expand Up @@ -515,8 +516,8 @@ h2 {
.editor-container {
width: 100%;
height: 100%;
max-width: 1000px;
min-height: 500px;
max-width: 900px;
min-height: 300px;
flex-grow: 1;
border: 2px solid #ccc;
border-radius: 10px;
Expand All @@ -533,10 +534,19 @@ h2 {
/* Header section styling */
.editor-header {
text-align: center;
margin-bottom: 20px;
margin-bottom: -10px;
margin-top: -60px;
}

.leave-btn,
.run-btn {
margin-top: 10px; /* Additional spacing if needed for each button */
}

#language-select {
margin-bottom: 20px;
}

/* Leave session button */
.leave-btn {
background-color: #ff4d4d;
Expand Down Expand Up @@ -586,3 +596,89 @@ h2 {
opacity: 1;
}
}

.editor-header2 {
text-align: center;
margin-bottom: 20px;
margin-top: 10px;
display: flex;
flex-direction: row; /* Arrange items in a vertical stack */
align-items: center; /* Align items to the left */
gap: 100px; /* Add vertical spacing between items */
}

.matching-form2 {
padding: 0px;
max-width: 40%;
margin: 0 auto; /* Center the form */
border-radius: 10px; /* Rounded corners for the form */
background-color: white;
}

/* Styles for inputs, textarea, and select within .question-form */
.matching-form2 input,
.matching-form2 textarea,
.matching-form2 select {
width: 100%;
padding: 10px;
margin-top: 5px; /* Space between input boxes */
border: 1px solid #ccc; /* Border */
border-radius: 4px; /* Rounded corners */
background-color: #f4f4f4;
color: #333;
font-size: 16px;
box-sizing: border-box; /* Ensures padding is included within the width */
}

/* Input Fields Focus State */
.matching-form2 input:focus,
.matching-form2 textarea:focus,
.matching-form2 select:focus {
outline: none;
border: 2px solid #4CAF50; /* Green border on focus */
background-color: #fff; /* White background on focus */
}

/* Custom styling for the difficulty select dropdown */
.matching-form2 select {
width: 100%;
padding: 10px;
margin-top: 5px;
border: 2px solid #ccc; /* border */
border-radius: 4px; /* Rounded corners */
background-color: #f9f9f9;
color: #333;
font-size: 16px;
appearance: none;
}

/* Focus state for select dropdown */
.matching-form2 select:focus {
outline: none;
border-color: #4CAF50; /* Green border on focus */
background-color: #fff; /* White background on focus */
}

/* Submit Button */
.matching-form2 button.submit-btn {
background-color: #4CAF50;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
margin-top: 10px;
}

.matching-form2 button.submit-btn:hover {
background-color: #45a049;
}

/* Error Message styling, to be expanded later most likely split into diff types */
.matching-form2 .error-message {
color: red;
font-size: 14px;
margin-bottom: 15px;
text-align: center;
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,50 @@
import React, { useState, useEffect, useRef } from 'react';
import { UnControlled as CodeMirror } from 'react-codemirror2';
import { useParams, useNavigate } from 'react-router-dom';
import axios from 'axios';
import * as Y from 'yjs';

import 'codemirror/lib/codemirror.css';
import 'codemirror/theme/material.css';
import 'codemirror/mode/javascript/javascript';
import axios from 'axios';
import 'codemirror/addon/hint/show-hint';
import 'codemirror/addon/hint/show-hint.css';
import 'codemirror/addon/hint/javascript-hint'; // For JavaScript hints

import * as Y from 'yjs';
import { WebsocketProvider } from 'y-websocket';
import 'codemirror/mode/javascript/javascript'; // For JavaScript
import 'codemirror/mode/clike/clike'; // For C, C++, Java (these use the 'clike' mode)
import 'codemirror/mode/python/python'; // For Python
import 'codemirror/mode/swift/swift'; // For Swift

// @ts-check
import { CodemirrorBinding } from 'y-codemirror';
import { WebsocketProvider } from 'y-websocket';


const CollaborationServiceIntegratedView: React.FC = () => {
const { topic, difficulty, questionId, sessionId } = useParams<{ topic: string; difficulty: string; questionId: string; sessionId: string; }>();
const [output, setOutput] = useState<string | null>(null);
const [language, setLanguage] = useState<number>(63); // Default to JavaScript (Node.js)
const [syntaxLang, setSyntaxLang] = useState<string>('javascript');
const editorRef = useRef<any>(null);
const navigate = useNavigate();
const [yText, setYText] = useState<Y.Text | null>(null);

// Mapping for CodeMirror modes
const languageModes = {
javascript: 'javascript',
cpp: 'text/x-c++src', // Mode for C++
c: 'text/x-csrc', // Mode for C
java: 'text/x-java', // Mode for Java
python: 'python', // Mode for Python
};

useEffect(() => {
console.log(`Session ID: ${sessionId}, Topic: ${topic}, Difficulty: ${difficulty}`);
console.log(`Question: ${questionId}`);
}, [sessionId, topic, difficulty, questionId]);

useEffect(() => {
document.body.style.overflow = 'hidden';
document.body.style.overflow = 'auto';
return () => {
document.body.style.overflow = 'auto';
};
Expand All @@ -51,6 +71,17 @@ const CollaborationServiceIntegratedView: React.FC = () => {
navigate('/matching');
};

const handleLangChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
setLanguage(parseInt(e.target.value));
setSyntaxLang(e.target.value === '63' ? 'javascript'
: e.target.value === '54' ? 'text/x-c++src'
: e.target.value === '50' ? 'text/x-csrc'
: e.target.value === '71' ? 'python'
: e.target.value === '62' ? 'text/x-java'
: e.target.value === '83' ? 'swift'
: 'javascript');
}

const handleRunCode = async () => {
try {
if (!yText) {
Expand Down Expand Up @@ -119,39 +150,77 @@ const CollaborationServiceIntegratedView: React.FC = () => {
<h2>Collaboration Session</h2>
<p>Topic: {topic} | Difficulty: {difficulty} | Session: {sessionId}</p>
<p>Question: {questionId}</p>
<button onClick={handleLeaveSession} className="leave-btn">Leave Session</button>
</div>
</div>

<div className="editor-header2">
<button
onClick={handleLeaveSession}
className="leave-btn"
style={{ marginBottom: '0px' }}
>
Leave Session
</button>

<div className="editor-container">
<CodeMirror
ref={editorRef}
options={{
mode: 'javascript',
lineNumbers: true,
tabSize: 2,
indentWithTabs: true
}}
onChange={() => {
// Let Yjs handle all updates; do not use setCode here
}}
/>
</div>
<div className="matching-form2">
<div>
<select
name="topic"
value={language}
onChange={
(e) => handleLangChange(e)
}
required
>
<option value="" disabled>Select Language</option> {/* Placeholder option */}
<option value="63">JavaScript</option>
<option value="54">C++</option>
<option value="50">C</option>
<option value="71">Python</option>
<option value="62">Java</option>
<option value="83">Swift</option>
</select>
</div>
</div>
<button
onClick={handleRunCode}
className="run-btn"
style={{ marginBottom: '0px' }}
> Run Code
</button>
</div>

<div className="editor-container">
<CodeMirror
ref={editorRef}
options={{
mode: syntaxLang,
lineNumbers: true,
tabSize: 2,
indentWithTabs: true,
showHint: true,
extraKeys: {
'Ctrl-Space': 'autocomplete', // Trigger autocomplete with Ctrl-Space
},
hintOptions: { completeSingle: false },
}}

<label htmlFor="language-select" style={{ marginTop: '20px' }}>Select Language:</label>
<select
id="language-select"
value={language}
onChange={(e) => setLanguage(parseInt(e.target.value))}
style={{ marginBottom: '20px' }}
>
<option value="63">JavaScript (Node.js)</option>
<option value="54">C++ (GCC 9.2.0)</option>
<option value="50">C (GCC 9.2.0)</option>
<option value="71">Python (3.8.1)</option>
<option value="62">Java (OpenJDK 13.0.1)</option>
</select>

<button onClick={handleRunCode} className="run-btn" style={{ marginBottom: '20px' }}>Run Code</button>
editorDidMount={(editor) => {
editor.on('keyup', (cm: any, event: any) => {
// Only trigger autocomplete on specific characters
const triggerKeys = /^[a-zA-Z0-9_]$/; // Allow letters, numbers, and underscore
if (
triggerKeys.test(event.key) &&
!cm.state.completionActive // Ensure that completion is not already active
) {
cm.showHint({ completeSingle: false });
}
});
}}
onChange={() => {
// Let Yjs handle all updates; do not use setCode here
}}
/>
</div>

<h3 style={{ textAlign: 'left', marginBottom: '5px' }}>Output</h3>
<div className="output-container" style={{ width: '900px', textAlign: 'left', border: '1px solid #ddd', padding: '10px', borderRadius: '5px', backgroundColor: '#f9f9f9' }}>
Expand Down

0 comments on commit c25d200

Please sign in to comment.