├── src ├── pages │ ├── home │ │ ├── home.css │ │ ├── components │ │ │ ├── CodeBlocks.jsx │ │ │ └── CodeBlock.jsx │ │ └── Home.jsx │ └── editor │ │ ├── editor.css │ │ ├── Editor.jsx │ │ └── components │ │ └── EditorBody.jsx ├── components │ ├── codexlogo.png │ ├── MaterialTheming.js │ ├── firebase.js │ └── Routes.js ├── index.js ├── App.js └── index.css ├── public ├── codexlogo.png └── index.html ├── netlify.toml ├── .gitignore ├── package.json └── README.md /src/pages/home/home.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/pages/editor/editor.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/codexlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arihant-jain-09/CodeX/master/public/codexlogo.png -------------------------------------------------------------------------------- /src/components/codexlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arihant-jain-09/CodeX/master/src/components/codexlogo.png -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | functions = "/lambda" 3 | command = "CI= npm run prod" 4 | 5 | [[redirects]] 6 | from = "/*" 7 | to = "/index.html" 8 | status = 200 -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | 4 | import App from "./App"; 5 | 6 | const rootElement = document.getElementById("root"); 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | rootElement 12 | ); 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dev dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | /lambda 14 | /.codesandbox 15 | /.netlify 16 | /backend 17 | 18 | # misc 19 | .DS_Store 20 | .env.local 21 | .env.development.local 22 | .env.test.local 23 | .env.production.local 24 | 25 | npm-debug.log* 26 | yarn-debug.log* 27 | yarn-error.log* 28 | -------------------------------------------------------------------------------- /src/components/MaterialTheming.js: -------------------------------------------------------------------------------- 1 | import { createMuiTheme } from "@material-ui/core"; 2 | 3 | const darkTheme = createMuiTheme({ 4 | palette: { 5 | type: "dark", 6 | primary: { 7 | main: "#2196F3" 8 | }, 9 | typography: { 10 | fontFamily: '"Poppins", sans-serif', 11 | color: "white" 12 | }, 13 | text: { 14 | primary: "#fff", 15 | hint: "#fff" 16 | }, 17 | background: { 18 | paper: "#19202b" 19 | } 20 | } 21 | }); 22 | 23 | export { darkTheme }; 24 | -------------------------------------------------------------------------------- /src/components/firebase.js: -------------------------------------------------------------------------------- 1 | import firebase from "firebase"; 2 | 3 | var firebaseConfig = { 4 | apiKey: "AIzaSyA2KhsWCTk8FQDpB440p4sJEeXq_NJ-1d8", 5 | authDomain: "rhythm-3ef06.firebaseapp.com", 6 | databaseURL: "https://rhythm-3ef06.firebaseio.com", 7 | projectId: "rhythm-3ef06", 8 | storageBucket: "rhythm-3ef06.appspot.com", 9 | messagingSenderId: "917983204838", 10 | appId: "1:917983204838:web:68cacc66e0f9940946b227", 11 | measurementId: "G-XYSWYMDDRH" 12 | }; 13 | firebase.initializeApp(firebaseConfig); 14 | firebase.analytics(); 15 | 16 | export default firebase; 17 | -------------------------------------------------------------------------------- /src/components/Routes.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | BrowserRouter as Router, 4 | Route, 5 | Redirect, 6 | Switch 7 | } from "react-router-dom"; 8 | 9 | import Editor from "../pages/editor/Editor"; 10 | import Home from "../pages/home/Home"; 11 | 12 | function Routes() { 13 | return ( 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ); 22 | } 23 | 24 | export default Routes; 25 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import "./index.css"; 3 | 4 | import Routes from "./components/Routes"; 5 | 6 | import { makeStyles, createStyles, Theme } from "@material-ui/core"; 7 | 8 | const useStyles = makeStyles((theme: Theme) => 9 | createStyles({ 10 | dynamicPage: { 11 | height: "100%", 12 | width: "100%" 13 | } 14 | }) 15 | ); 16 | 17 | export default function App() { 18 | const classes = useStyles(); 19 | 20 | return ( 21 |
22 |
23 | 24 |
25 |
26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Poppins&display=swap"); 2 | 3 | .App { 4 | position: absolute; 5 | margin: auto; 6 | top: 0; 7 | right: 0; 8 | left: 0; 9 | bottom: 0; 10 | font-family: sans-serif; 11 | text-align: center; 12 | padding: 10px; 13 | } 14 | 15 | body { 16 | background: #19202b; 17 | } 18 | 19 | body * { 20 | font-family: Poppins, sans-serif; 21 | box-sizing: border-box; 22 | } 23 | 24 | @media (max-width: 600px) { 25 | body { 26 | padding: 8px; 27 | } 28 | *::-webkit-scrollbar { 29 | display: none; 30 | } 31 | } 32 | 33 | *::-webkit-scrollbar { 34 | background: rgba(38, 47, 61, 0.44); 35 | } 36 | *::-webkit-scrollbar-thumb { 37 | background-color: #262f3d; 38 | } 39 | *::-webkit-scrollbar-thumb:hover { 40 | background-color: #465162; 41 | } 42 | -------------------------------------------------------------------------------- /src/pages/home/components/CodeBlocks.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { makeStyles, createStyles, Theme } from "@material-ui/core"; 4 | 5 | import CodeBlock from "./CodeBlock"; 6 | 7 | const useStyles = makeStyles((theme: Theme) => 8 | createStyles({ 9 | codeBlocks: { 10 | textAlign: "left" 11 | } 12 | }) 13 | ); 14 | 15 | function CodeBlocks({ classCodes }) { 16 | const classes = useStyles(); 17 | 18 | console.log(classCodes); 19 | 20 | return ( 21 |
22 | {classCodes.map((codeBlockData, blockIndex) => ( 23 | 29 | ))} 30 |
31 | ); 32 | } 33 | 34 | export default CodeBlocks; 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codex", 3 | "version": "1.0.0", 4 | "description": "", 5 | "keywords": [], 6 | "main": "src/index.js", 7 | "dependencies": { 8 | "@material-ui/core": "4.11.1", 9 | "@material-ui/icons": "4.9.1", 10 | "@material-ui/styles": "4.11.1", 11 | "axios": "0.21.0", 12 | "firebase": "8.1.1", 13 | "netlify-cli": "^2.69.3", 14 | "netlify-lambda": "^2.0.1", 15 | "react": "17.0.0", 16 | "react-ace": "9.2.0", 17 | "react-dom": "17.0.0", 18 | "react-router-dom": "5.2.0", 19 | "react-scripts": "3.4.3" 20 | }, 21 | "devDependencies": { 22 | "typescript": "3.8.3" 23 | }, 24 | "scripts": { 25 | "start": "react-scripts start", 26 | "build": "react-scripts build", 27 | "test": "react-scripts test --env=jsdom", 28 | "eject": "react-scripts eject", 29 | "start:lambda": "netlify-lambda serve backend", 30 | "build:lambda": "netlify-lambda build backend", 31 | "prod": "CI= npm run build; CI= npm run build:lambda" 32 | }, 33 | "browserslist": [ 34 | ">0.2%", 35 | "not dead", 36 | "not ie <= 11", 37 | "not op_mini all" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /src/pages/home/components/CodeBlock.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useHistory } from "react-router-dom"; 3 | 4 | import { Button, makeStyles, createStyles, Theme } from "@material-ui/core"; 5 | import { DeleteRoundedIcon } from "@material-ui/icons"; 6 | 7 | const useStyles = makeStyles((theme: Theme) => 8 | createStyles({ 9 | codeBlock: { 10 | display: "inline-block", 11 | height: "fit-content", 12 | width: "fit-content", 13 | borderRadius: "5px", 14 | border: "2px solid #2196F3", 15 | paddingBottom: "40px", 16 | cursor: "pointer", 17 | margin: "0px 4px 10px 4px", 18 | "& :hover": { 19 | color: "white" 20 | } 21 | }, 22 | title: { 23 | color: "#2196F3", 24 | padding: 7, 25 | borderBottom: "2px solid #2196F3", 26 | fontSize: "14px" 27 | } 28 | }) 29 | ); 30 | 31 | function CodeBlock({ blockTitle, blockLang, blockLink }) { 32 | const classes = useStyles(); 33 | const history = useHistory(); 34 | 35 | const [title, setTitle] = React.useState(blockTitle); 36 | 37 | return ( 38 |
{ 41 | history.push(blockLink); 42 | }} 43 | > 44 |
{title + "." + blockLang}
45 | {/* */} 54 |
55 | ); 56 | } 57 | 58 | export default CodeBlock; 59 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 16 | 25 | CodeX 26 | 27 | 28 | 29 | 32 |
33 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/pages/editor/Editor.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useHistory } from "react-router-dom"; 3 | 4 | import brandingLogo from "../../components/codexlogo.png"; 5 | import "./editor.css"; 6 | 7 | import { makeStyles, createStyles, Theme } from "@material-ui/core"; 8 | import { ThemeProvider } from "@material-ui/styles"; 9 | import { darkTheme } from "../../components/MaterialTheming"; 10 | 11 | import EditorBody from "./components/EditorBody"; 12 | 13 | import firebase from "../../components/firebase.js"; 14 | 15 | const useStyles = makeStyles((theme: Theme) => 16 | createStyles({ 17 | editorPage: { 18 | height: "100%", 19 | width: "100%", 20 | display: "grid", 21 | gridGap: "14px", 22 | gridTemplateRows: "auto 1fr" 23 | }, 24 | brandingLogo: { 25 | cursor: "pointer" 26 | }, 27 | header: { 28 | display: "grid", 29 | gridTemplateColumns: "repeat(3,1fr)", 30 | "& > *": { 31 | margin: "auto 0" 32 | } 33 | }, 34 | codeTitle: { 35 | color: "#2196F3", 36 | backgroundColor: "transparent", 37 | border: "none", 38 | outline: "none", 39 | textAlign: "center", 40 | height: "100%", 41 | width: "100%" 42 | }, 43 | body: { 44 | height: "100%", 45 | width: "100%", 46 | display: "grid", 47 | gridTemplateRows: "70% 30%" 48 | } 49 | }) 50 | ); 51 | 52 | function Editor(props) { 53 | const classes = useStyles(); 54 | const history = useHistory(); 55 | const [className, setClassName] = React.useState(""), 56 | [notOwner, setNotOwner] = React.useState(false); 57 | 58 | // let notOwner = true; 59 | 60 | // function setNotOwner(bool) { 61 | // notOwner = bool; 62 | // } 63 | 64 | React.useEffect(() => { 65 | firebase 66 | .database() 67 | .ref("CodeX/" + props.match.params.editorID + "/className") 68 | .once("value") 69 | .then((snap) => { 70 | setClassName(snap.val()); 71 | }); 72 | if ( 73 | localStorage.getItem("codex-codes") && 74 | JSON.parse(localStorage.getItem("codex-codes"))[ 75 | props.match.params.editorIndex 76 | ].key === props.match.params.editorID 77 | ) 78 | setNotOwner(true); 79 | }, []); 80 | 81 | React.useEffect(() => { 82 | if (className.trim() !== "" && notOwner) { 83 | firebase 84 | .database() 85 | .ref("CodeX/" + props.match.params.editorID + "/className") 86 | .set(className); 87 | 88 | console.log(localStorage.getItem("codex-codes")); 89 | if (localStorage.getItem("codex-codes")) { 90 | let classNames = JSON.parse(localStorage.getItem("codex-codes")); 91 | classNames[props.match.params.editorIndex].name = className; 92 | localStorage.setItem("codex-codes", JSON.stringify(classNames)); 93 | } 94 | } 95 | }, [className]); 96 | 97 | return ( 98 | 99 |
100 |
101 | branding-logo { 106 | history.push("/"); 107 | }} 108 | /> 109 | { 112 | setClassName(e.target.value); 113 | }} 114 | className={classes.codeTitle} 115 | spellCheck={false} 116 | readOnly={!notOwner} 117 | /> 118 |
119 | 123 |
124 |
125 | ); 126 | } 127 | 128 | export default Editor; 129 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [CodeX](https://codexweb.netlify.app) 2 | CodeX is an online compiler for various languages like Java, C++, Python, etc. 3 | 4 | [![CodeX Editor](https://dev-to-uploads.s3.amazonaws.com/i/6f0l70d73sf7m7razxmt.png)](https://codexweb.netlify.app) 5 | 6 | CodeX has a simple UI in order to store all your codes written in various languages easily at one place. 7 | 8 | [![CodeX Home](https://dev-to-uploads.s3.amazonaws.com/i/07a4naxeav1uunz9b8ne.png)](https://codexweb.netlify.app) 9 | 10 | You can share the codes' links that you write with your friends without being worried about them making any changes. 11 | CodeX stores all your code details on your device, which means every code that you write will only be editable on the 12 | device where you write you code in. Every Code shares a key that only your device and CodeX's backend know, so don't 13 | fear about others making any changes. Although there are ways to hack into others code and make changes but that's for 14 | you to find out. Once you find it out simply create an issue reporting the bug. 15 | 16 | No need to Sign In / Sign Up in order to execute and save your code. Every code automatically saves and updates in realtime 17 | so don't worry about losing it. It will always live in your computer unless you decide to clear your cache. 18 | 19 | ## Something special for other developers 20 | 21 | ### Introducing the CodeX API, 22 | 23 | Here's how you can execute code in various languages on your own website for free (no, there's no fucking catch, it's literally free), 24 | 25 | ### Execute Code and fetch output 26 | 27 | #### `POST` /.netlify/functions/enforceCode 28 | This endpoint allows you to execute your script and fetch output results. 29 | 30 | ### What are the Input Parameters for execute api call? 31 | 32 | | Parameter | Description | 33 | |------------|------------------------------------------------------------------------------------------------------------------------------| 34 | | "code" | Should contain the script that needs to be executed | 35 | | "language" | Language that the script is written in for example: java, cpp, etc. (Check language as a payload down below in next question)| 36 | | "input" | In case the script requires any kind of input for execution, leave empty if no input required | 37 | 38 | ### What are the languages that are supported for execution? 39 | Whichever language you might mention in the language field, it would be automatically executed with the latest version of it's compiler. 40 | 41 | | Languages | Language as a payload | 42 | |-----------|-----------------------| 43 | | C++ | cpp | 44 | | C | c | 45 | | C# | cs | 46 | | Java | java | 47 | | Python | py | 48 | | Ruby | rb | 49 | | Kotlin | kt | 50 | | Swift | swift | 51 | 52 | ### What if I have multiple inputs? 53 | Whenever taking inputs, make sure to take inputs from a textarea. This would allow the user to make multi-line 54 | inputs, in order to take multiple inputs, the user needs to input every value line by line individually in order 55 | for the backend to differentiate between multiple inputs. 56 | 57 | ### NodeJS Example to Execute API Call? 58 | ```javascript 59 | var axios = require('axios'); 60 | var data = JSON.stringify({ 61 | "code":`public class program{ 62 | public static void main(String [] args){ 63 | System.out.println(5+5+6); 64 | } 65 | }`, 66 | "language":"java", 67 | "input":"" 68 | }); 69 | 70 | var config = { 71 | method: 'post', 72 | url: 'https://codexweb.netlify.app/.netlify/functions/enforceCode', 73 | headers: { 74 | 'Content-Type': 'application/json' 75 | }, 76 | data : data 77 | }; 78 | 79 | axios(config) 80 | .then(function (response) { 81 | console.log(response.data); 82 | }) 83 | .catch(function (error) { 84 | console.log(error); 85 | }); 86 | ``` 87 | 88 | ### Sample Output 89 | The output is a JSON object comprising only one parameter that is the output. 90 | 91 | ```json 92 | { 93 | "output":"16\n" 94 | } 95 | ``` 96 | 97 | This project will not accept any PRs, I will only respond to issues created. There's a few stuff/code that have not been 98 | shared for obvious reasons. 99 | 100 | Happy hacking! -------------------------------------------------------------------------------- /src/pages/home/Home.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useHistory } from "react-router-dom"; 3 | 4 | import brandingLogo from "../../components/codexlogo.png"; 5 | import "./home.css"; 6 | 7 | import { 8 | Button, 9 | ButtonGroup, 10 | Backdrop, 11 | TextField, 12 | MenuItem, 13 | Select, 14 | FormControl, 15 | InputLabel, 16 | makeStyles, 17 | createStyles, 18 | Theme 19 | } from "@material-ui/core"; 20 | import { ThemeProvider } from "@material-ui/styles"; 21 | import { darkTheme } from "../../components/MaterialTheming"; 22 | 23 | import firebase from "../../components/firebase.js"; 24 | 25 | import CodeBlocks from "./components/CodeBlocks"; 26 | 27 | const useStyles = makeStyles((theme: Theme) => 28 | createStyles({ 29 | homePage: { 30 | height: "100%", 31 | width: "100%" 32 | }, 33 | header: { 34 | width: "100%", 35 | display: "grid", 36 | gridGap: "20px 0", 37 | gridTemplateColumns: "repeat(3, 33.5%)", 38 | textAlign: "center", 39 | "& > *": { 40 | margin: "auto 0" 41 | }, 42 | [theme.breakpoints.down("sm")]: { 43 | gridTemplateColumns: "unset", 44 | gridTemplateRows: "repeat(3, auto)" 45 | } 46 | }, 47 | brandingLogo: { 48 | cursor: "pointer" 49 | }, 50 | buttonGroup: { 51 | "& .MuiButton-outlinedPrimary": { 52 | borderWidth: "3px" 53 | }, 54 | margin: "auto", 55 | width: "100%", 56 | [theme.breakpoints.down("sm")]: { 57 | margin: 0 58 | } 59 | }, 60 | button: { 61 | width: "100%", 62 | "& span": { 63 | textTransform: "none", 64 | color: "#fff" 65 | } 66 | }, 67 | codeblocks: { 68 | width: "100%", 69 | marginTop: "10px", 70 | height: "calc(100% - 65px)", 71 | [theme.breakpoints.down("sm")]: { 72 | height: "calc(100% - 115px)" 73 | } 74 | }, 75 | backdrop: { 76 | zIndex: theme.zIndex.drawer + 1, 77 | color: "#fff" 78 | }, 79 | createClassModal: { 80 | height: "fit-content", 81 | width: "90%", 82 | maxHeight: 300, 83 | maxWidth: 400, 84 | background: "#19202b", 85 | borderRadius: "5px", 86 | padding: 15, 87 | textAlign: "left", 88 | "& span": { 89 | display: "block" 90 | } 91 | }, 92 | modalTitle: { 93 | fontSize: "20px" 94 | }, 95 | modalDesc: { 96 | color: "#2196F3", 97 | fontSize: "13px" 98 | }, 99 | modalInput: { 100 | width: "100%", 101 | marginTop: "10px" 102 | }, 103 | modalSelect: { 104 | width: "100%", 105 | marginTop: "20px" 106 | }, 107 | modalButton: { 108 | margin: "20px 10px 4px 0" 109 | } 110 | }) 111 | ); 112 | 113 | function Home() { 114 | const classes = useStyles(); 115 | const history = useHistory(); 116 | 117 | const [theme, setTheme] = React.useState(darkTheme), 118 | [modalOpen, setModalOpen] = React.useState(false), 119 | [classCodes, setClassCodes] = React.useState([]); 120 | 121 | React.useEffect(() => { 122 | if (localStorage.getItem("codex-codes")) 123 | setClassCodes(JSON.parse(localStorage.getItem("codex-codes"))); 124 | }, []); 125 | React.useEffect(() => { 126 | localStorage.setItem("codex-codes", JSON.stringify(classCodes)); 127 | }, [classCodes]); 128 | 129 | function CreateClass() { 130 | const [inputClassName, setInputClassName] = React.useState(""); 131 | const [lang, selectlang] = React.useState("cpp"); 132 | 133 | function createNewClass() { 134 | console.log("Creating new class..."); 135 | firebase 136 | .database() 137 | .ref("CodeX") 138 | .push({ 139 | className: inputClassName, 140 | language: lang, 141 | code: `` 142 | }) 143 | .then((snap) => { 144 | console.log(classCodes); 145 | setClassCodes([ 146 | ...classCodes, 147 | { name: inputClassName, key: snap.key, lang: lang } 148 | ]); 149 | history.push("/" + classCodes.length + "/" + snap.key); 150 | }); 151 | setModalOpen(false); 152 | } 153 | 154 | function SelectCode() { 155 | return ( 156 | 157 | Language 158 | 175 | 176 | ); 177 | } 178 | 179 | return ( 180 | { 184 | setModalOpen(false); 185 | }} 186 | > 187 |
{ 190 | e.stopPropagation(); 191 | }} 192 | > 193 | Create New Class 194 | 195 | Please enter a proper class name and choose language 196 | 197 | { 204 | setInputClassName(e.target.value); 205 | }} 206 | /> 207 | 208 | 216 | 226 |
227 |
228 | ); 229 | } 230 | 231 | return ( 232 |
233 | 234 |
235 | branding-logo { 240 | history.push("/"); 241 | }} 242 | /> 243 | 249 | 257 | 265 | 273 | 274 |
275 |
276 | 277 |
278 | 279 |
280 |
281 | ); 282 | } 283 | 284 | export default Home; 285 | -------------------------------------------------------------------------------- /src/pages/editor/components/EditorBody.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import AceEditor from "react-ace"; 4 | import "ace-builds/src-noconflict/theme-dracula"; 5 | import "ace-builds/src-noconflict/mode-java"; 6 | import "ace-builds/src-noconflict/mode-c_cpp"; 7 | import "ace-builds/src-noconflict/mode-csharp"; 8 | import "ace-builds/src-noconflict/mode-python"; 9 | import "ace-builds/src-noconflict/mode-ruby"; 10 | import "ace-builds/src-noconflict/mode-kotlin"; 11 | import "ace-builds/src-noconflict/mode-swift"; 12 | 13 | import { 14 | Button, 15 | TextField, 16 | Select, 17 | MenuItem, 18 | makeStyles, 19 | createStyles, 20 | Backdrop, 21 | CircularProgress, 22 | LinearProgress, 23 | Theme 24 | } from "@material-ui/core"; 25 | import PlayArrowRoundedIcon from "@material-ui/icons/PlayArrowRounded"; 26 | import { ThemeProvider } from "@material-ui/styles"; 27 | import { darkTheme } from "../../../components/MaterialTheming"; 28 | 29 | import firebase from "../../../components/firebase.js"; 30 | import axios from "axios"; 31 | 32 | const useStyles = makeStyles((theme: Theme) => 33 | createStyles({ 34 | body: { 35 | display: "grid", 36 | gridGap: "0 20px", 37 | gridTemplateRows: "calc(100% - 200px) 200px", 38 | // "& .ace_selection": { 39 | // background: "#ff711e36 !important" 40 | // }, 41 | "& .ace_gutter": { 42 | backgroundColor: "#19202b" 43 | }, 44 | "& .ace_editor": { 45 | backgroundColor: "#19202b" 46 | }, 47 | "& .ace_support.ace_function": { 48 | color: "#2196F3" 49 | }, 50 | [theme.breakpoints.up("sm")]: { 51 | gridTemplateRows: "unset", 52 | gridTemplateColumns: "calc(100% - 350px) 330px" 53 | } 54 | }, 55 | backdrop: { 56 | zIndex: theme.zIndex.drawer + 1, 57 | color: "#fff" 58 | }, 59 | editor: { 60 | height: "100% !important", 61 | width: "100% !important", 62 | borderBottom: "2px solid #2196F3", 63 | "& *": { 64 | fontFamily: "monospace" 65 | }, 66 | [theme.breakpoints.up("sm")]: { 67 | borderBottom: "none", 68 | borderRight: "2px solid #2196F3" 69 | } 70 | }, 71 | output: { 72 | display: "grid", 73 | gridTemplateRows: "auto 1fr auto" 74 | }, 75 | selectlang: { 76 | height: "32px", 77 | margin: "7px 0", 78 | textAlign: "left !important" 79 | }, 80 | runPanel: { 81 | textAlign: "left !important" 82 | }, 83 | runBtn: { 84 | marginRight: 10 85 | }, 86 | inputModal: { 87 | height: "fit-content", 88 | width: "90%", 89 | maxHeight: 500, 90 | maxWidth: 400, 91 | background: "#19202b", 92 | borderRadius: "5px", 93 | padding: 15, 94 | textAlign: "left", 95 | "& text": { 96 | display: "block", 97 | color: "#2196F3", 98 | fontSize: "20px" 99 | }, 100 | "& smallertext": { 101 | display: "block", 102 | fontSize: "14px" 103 | } 104 | }, 105 | modalInput: { 106 | width: "100%", 107 | marginTop: "10px" 108 | }, 109 | runBtnOnModal: { 110 | marginTop: "20px" 111 | }, 112 | buttonProgress: { 113 | color: "white", 114 | margin: "auto" 115 | }, 116 | outputTitle: { 117 | color: "#2196F3", 118 | margin: "7px 0", 119 | textAlign: "left !important" 120 | }, 121 | outputTerminal: { 122 | textAlign: "left", 123 | color: "white", 124 | overflow: "auto", 125 | whiteSpace: "pre-line", 126 | fontFamily: "monospace", 127 | fontSize: "17px" 128 | } 129 | }) 130 | ); 131 | 132 | function EditorBody({ storeAt, index }) { 133 | const classes = useStyles(); 134 | const [codeFontSize, setCodeFontSize] = React.useState(20), 135 | [showLoader, setShowLoader] = React.useState(true), 136 | [lang, selectlang] = React.useState(""), 137 | [editorLanguage, setEditorLanguage] = React.useState("c_cpp"), 138 | [code, setCode] = React.useState(``), 139 | [outputValue, setOutputValue] = React.useState(""), 140 | [takeInput, setTakeInput] = React.useState(false), 141 | [executing, setExecuting] = React.useState(false), 142 | [input, setInput] = React.useState(""); 143 | 144 | let notOwner = true; 145 | 146 | function setNotOwner(bool) { 147 | notOwner = bool; 148 | } 149 | 150 | if ( 151 | localStorage.getItem("codex-codes") && 152 | JSON.parse(localStorage.getItem("codex-codes"))[index].key === 153 | storeAt.substring(storeAt.indexOf("/") + 1) 154 | ) 155 | setNotOwner(false); 156 | console.log("Let edit: " + notOwner); 157 | 158 | console.log(storeAt); 159 | 160 | window.addEventListener("resize", (e) => { 161 | if (window.innerWidth > 600) { 162 | setCodeFontSize(20); 163 | } else { 164 | setCodeFontSize(14); 165 | } 166 | }); 167 | 168 | React.useEffect(() => { 169 | if (window.innerWidth > 600) setCodeFontSize(20); 170 | else setCodeFontSize(14); 171 | 172 | firebase 173 | .database() 174 | .ref(storeAt) 175 | .once("value") 176 | .then((snap) => { 177 | setShowLoader(false); 178 | selectlang(snap.val().language); 179 | setCode(snap.val().code); 180 | }); 181 | }, []); 182 | 183 | React.useEffect(() => { 184 | if (lang !== "") { 185 | let langArray = { 186 | cpp: "c_cpp", 187 | java: "java", 188 | c: "c_cpp", 189 | cs: "csharp", 190 | rb: "ruby", 191 | py: "python", 192 | kt: "kotlin", 193 | swift: "swift" 194 | }; 195 | console.log(langArray[lang]); 196 | setEditorLanguage(langArray[lang]); 197 | } 198 | if (lang !== "" && !notOwner) { 199 | firebase 200 | .database() 201 | .ref(storeAt + "/language") 202 | .set(lang); 203 | if (localStorage.getItem("codex-codes")) { 204 | let classNames = JSON.parse(localStorage.getItem("codex-codes")); 205 | classNames[index].lang = lang; 206 | localStorage.setItem("codex-codes", JSON.stringify(classNames)); 207 | } 208 | } 209 | }, [lang]); 210 | 211 | React.useEffect(() => { 212 | if (code.trim() !== "" && !notOwner) { 213 | firebase 214 | .database() 215 | .ref(storeAt + "/code") 216 | .set(code); 217 | } 218 | }, [code]); 219 | 220 | const createExecutionRequest = () => { 221 | setTakeInput(false); 222 | setExecuting(true); 223 | var data = { 224 | code: code, 225 | language: lang, 226 | input: input 227 | }; 228 | 229 | var config = { 230 | method: "post", 231 | url: 232 | "/.netlify/functions/enforceCode", 233 | headers: { 234 | "Content-Type": "application/json" 235 | }, 236 | data: data 237 | }; 238 | 239 | axios(config) 240 | .then(function (response) { 241 | setExecuting(false); 242 | setOutputValue(response.data.output); 243 | }) 244 | .catch(function (error) { 245 | setExecuting(false); 246 | setOutputValue("Network Error"); 247 | }); 248 | }; 249 | 250 | function SelectLanguage() { 251 | return ( 252 | 273 | ); 274 | } 275 | 276 | return ( 277 | 278 | { 282 | setShowLoader(false); 283 | }} 284 | > 285 | 286 | 287 | { 291 | setTakeInput(false); 292 | setExecuting(false); 293 | }} 294 | > 295 |
{ 298 | e.stopPropagation(); 299 | }} 300 | > 301 | Input 302 | 303 | If your code requires an input, please type it down below otherwise 304 | leave it empty. For multiple inputs, type in all your inputs line by 305 | line. 306 | 307 | { 314 | setInput(e.target.value); 315 | }} 316 | spellCheck={false} 317 | rowsMax={7} 318 | multiline 319 | /> 320 | 329 |
330 |
331 |
332 | { 336 | setCode(e); 337 | }} 338 | name="UNIQUE_ID_OF_DIV" 339 | setOptions={{ 340 | showPrintMargin: false, 341 | fontSize: codeFontSize 342 | }} 343 | value={code} 344 | className={classes.editor} 345 | readOnly={notOwner} 346 | /> 347 |
348 |
Output
349 |
{`${outputValue}`}
350 |
351 | 364 | 365 | {executing && ( 366 | 367 | )} 368 |
369 |
370 |
371 |
372 | ); 373 | } 374 | 375 | export default EditorBody; 376 | --------------------------------------------------------------------------------