diff --git a/peerprep/frontend/src/styles/App.css b/peerprep/frontend/src/styles/App.css index d49d151f5b..4b037f56c8 100644 --- a/peerprep/frontend/src/styles/App.css +++ b/peerprep/frontend/src/styles/App.css @@ -3,6 +3,7 @@ margin: 0 auto; padding: 5rem; text-align: center; + background-color: white; } /* Global Styling */ @@ -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; @@ -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; @@ -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; +} diff --git a/peerprep/frontend/src/views/CollabServiceViews/CollabServiceIntegratedView.tsx b/peerprep/frontend/src/views/CollabServiceViews/CollabServiceIntegratedView.tsx index 8ba7c6d93a..ce83c9a18c 100644 --- a/peerprep/frontend/src/views/CollabServiceViews/CollabServiceIntegratedView.tsx +++ b/peerprep/frontend/src/views/CollabServiceViews/CollabServiceIntegratedView.tsx @@ -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(null); const [language, setLanguage] = useState(63); // Default to JavaScript (Node.js) + const [syntaxLang, setSyntaxLang] = useState('javascript'); const editorRef = useRef(null); const navigate = useNavigate(); const [yText, setYText] = useState(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'; }; @@ -51,6 +71,17 @@ const CollaborationServiceIntegratedView: React.FC = () => { navigate('/matching'); }; + const handleLangChange = (e: React.ChangeEvent) => { + 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) { @@ -119,39 +150,77 @@ const CollaborationServiceIntegratedView: React.FC = () => {

Collaboration Session

Topic: {topic} | Difficulty: {difficulty} | Session: {sessionId}

Question: {questionId}

- - + + +
+ -
- { - // Let Yjs handle all updates; do not use setCode here - }} - /> -
+
+
+ +
+
+ +
+ +
+ Select Language: - - - + 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 + }} + /> +

Output